home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 1994-04-01 | 1.5 MB | 41,763 lines | [ TEXT/R*ch]
Text Truncated. Only the first 1MB is shown below. Download the file for the complete contents.
Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA20530 (5.65b/3.6/CWI-Amsterdam); Sat, 9 Jan 1993 21:31:07 +0100 Received: by voorn.cwi.nl with SMTP id AA04917 (5.65b/3.5/CWI-Amsterdam); Sat, 9 Jan 1993 21:31:05 +0100 Message-Id: <9301092031.AA04917.guido@voorn.cwi.nl> To: python-list@cwi.nl Subject: Python 0.9.8 released From: Guido.van.Rossum@cwi.nl X-Organization: CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Sat, 09 Jan 1993 21:31:04 +0100 Sender: Guido.van.Rossum@cwi.nl I have finally released the long-awaited Python version 0.9.8. Boy has it been a heavy delivery! But the baby is healthy as can be... You can ftp it from the following sites: Location Site IP address Directory Amsterdam ftp.cwi.nl 192.16.184.180 /pub/python U.S.A. wuarchive.wustl.edu 128.252.135.4 /pub The filename is python0.9.8.tar.Z. (Note the changed directory name on ftp.cwi.nl!) There's also a file containing PostScript of the documentation (tutorial, reference, library): pythondoc-ps0.9.8.tar.Z. I'm sorry, there are no Mac or PC versions yet. The version on wuarchive is likely to evaporate some time after it is installed; I will try to make sure that the version on ftp.cwi.nl is always there. You are invited to copy these files to other ftp archives to which you have access. Below is an exhaustive list of changes since 0.9.6 (which most of you are probably still using). If you wonder what happened to 0.9.7: there was a 0.9.7beta, which was a little rough, and instead of polishing it up a bit, I went ahead and made many more changes, so eventually I felt myself forced to call it 0.9.8. If you experience any kind of trouble with building or using 0.9.8, please mail a short description giving as much detail as possible about what system and configuration you are using and what kind of error messages you get, either to the list, or to me (if you fear it might be your own fault and don't want to be embarrassed). In all cases I will try to do something about it, providing either a work-around or patch. --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> ============================== ==> NEWS FOR RELEASE 0.9.8 <== ============================== I claim no completeness here, but I've tried my best to scan the log files throughout my source tree for interesting bits of news. A more complete account of the changes is to be found in the various ChangeLog files. See also "News for release 0.9.7beta" below if you're still using release 0.9.6, and the file HISTORY if you have an even older release. --Guido Changes to the language proper ------------------------------ There's only one big change: the conformance checking for function argument lists (of user-defined functions only) is stricter. Earlier, you could get away with the following: (a) define a function of one argument and call it with any number of arguments; if the actual argument count wasn't one, the function would receive a tuple containing the arguments arguments (an empty tuple if there were none). (b) define a function of two arguments, and call it with more than two arguments; if there were more than two arguments, the second argument would be passed as a tuple containing the second and further actual arguments. (Note that an argument (formal or actual) that is a tuple is counted as one; these rules don't apply inside such tuples, only at the top level of the argument list.) Case (a) was needed to accommodate variable-length argument lists; there is now an explicit "varargs" feature (precede the last argument with a '*'). Case (b) was needed for compatibility with old class definitions: up to release 0.9.4 a method with more than one argument had to be declared as "def meth(self, (arg1, arg2, ...)): ...". Version 0.9.6 provide better ways to handle both casees, bot provided backward compatibility; version 0.9.8 retracts the compatibility hacks since they also cause confusing behavior if a function is called with the wrong number of arguments. There's a script that helps converting classes that still rely on (b), provided their methods' first argument is called "self": demo/scripts/methfix.py. If this change breaks lots of code you have developed locally, try #defining COMPAT_HACKS in ceval.c. (There's a third compatibility hack, which is the reverse of (a): if a function is defined with two or more arguments, and called with a single argument that is a tuple with just as many arguments, the items of this tuple will be used as the arguments. Although this can (and should!) be done using the built-in function apply() instead, it isn't withdrawn yet.) One minor change: comparing instance methods works like expected, so that if x is an instance of a user-defined class and has a method m, then (x.m==x.m) yields 1. The following was already present in 0.9.7beta, but not explicitly mentioned in the NEWS file: user-defined classes can now define types that behave in almost allrespects like numbers. See demo/classes/Rat.py for a simple example. Changes to the build process ---------------------------- The Configure.py script and the Makefile has been made somewhat more bullet-proof, after reports of (minor) trouble on certain platforms. There is now a script to patch Makefile and config.c to add a new optional built-in module: Addmodule.sh. Read the script before using! Useing Addmodule.sh, all optional modules can now be configured at compile time using Configure.py, so there are no modules left that require dynamic loading. The Makefile has been fixed to make it easier to use with the VPATH feature of some Make versions (e.g. SunOS). Changes affecting portability ----------------------------- Several minor portability problems have been solved, e.g. "malloc.h" has been renamed to "mymalloc.h", "strdup.c" is no longer used, and the system now tolerates malloc(0) returning 0. For dynamic loading on the SGI, Jack Jansen's dl 1.6 is now distributed with Python. This solves several minor problems, in particular scripts invoked using #! can now use dynamic loading. Changes to the interpreter interface ------------------------------------ On popular demand, there's finally a "profile" feature for interactive use of the interpreter. If the environment variable $PYTHONSTARTUP is set to the name of an existing file, Python statements in this file are executed when the interpreter is started in interactive mode. There is a new clean-up mechanism, complementing try...finally: if you assign a function object to sys.exitfunc, it will be called when Python exits or receives a SIGTERM or SIGHUP signal. The interpreter is now generally assumed to live in /usr/local/bin/python (as opposed to /usr/local/python). The script demo/scripts/fixps.py will update old scripts in place (you can easily modify it to do other similar changes). Most I/O that uses sys.stdin/stdout/stderr will now use any object assigned to those names as long as the object supports readline() or write() methods. The parser stack has been increased to 500 to accommodate more complicated expressions (7 levels used to be the practical maximum, it's now about 38). The limit on the size of the *run-time* stack has completely been removed -- this means that tuple or list displays can contain any number of elements (formerly more than 50 would crash the interpreter). Changes to existing built-in functions and methods -------------------------------------------------- The built-in functions int(), long(), float(), oct() and hex() now also apply to class instalces that define corresponding methods (__int__ etc.). New built-in functions ---------------------- The new functions str() and repr() convert any object to a string. The function repr(x) is in all respects equivalent to `x` -- some people prefer a function for this. The function str(x) does the same except if x is already a string -- then it returns x unchanged (repr(x) adds quotes and escapes "funny" characters as octal escapes). The new function cmp(x, y) returns -1 if x<y, 0 if x==y, 1 if x>y. Changes to general built-in modules ----------------------------------- The time module's functions are more general: time() returns a floating point number and sleep() accepts one. Their accuracies depends on the precision of the system clock. Millisleep is no longer needed (although it still exists for now), but millitimer is still needed since on some systems wall clock time is only available with seconds precision, while a source of more precise time exists that isn't synchronized with the wall clock. (On UNIX systems that support the BSD gettimeofday() function, time.time() is as time.millitimer().) The string representation of a file object now includes an address: '<file 'filename', mode 'r' at #######>' where ###### is a hex number (the object's address) to make it unique. New functions added to posix: nice(), setpgrp(), and if your system supports them: setsid(), setpgid(), tcgetpgrp(), tcsetpgrp(). Improvements to the socket module: socket objects have new methods getpeername() and getsockname(), and the {get,set}sockopt methods can now get/set any kind of option using strings built with the new struct module. And there's a new function fromfd() which creates a socket object given a file descriptor (useful for servers started by inetd, which have a socket connected to stdin and stdout). Changes to SGI-specific built-in modules ---------------------------------------- The FORMS library interface (fl) now requires FORMS 2.1a. Some new functions have been added and some bugs have been fixed. Additions to al (audio library interface): added getname(), getdefault() and getminmax(). The gl modules doesn't call "foreground()" when initialized (this caused some problems) like it dit in 0.9.7beta (but not before). There's a new gl function 'gversion() which returns a version string. The interface to sv (Indigo video interface) has totally changed. (Sorry, still no documentation, but see the examples in demo/sgi/{sv,video}.) Changes to standard library modules ----------------------------------- Most functions in module string are now much faster: they're actually implemented in C. The module containing the C versions is called "strop" but you should still import "string" since strop doesn't provide all the interfaces defined in string (and strop may be renamed to string when it is complete in a future release). string.index() now accepts an optional third argument giving an index where to start searching in the first argument, so you can find second and further occurrences (this is similar to the regular expression functions in regex). The definition of what string.splitfields(anything, '') should return is changed for the last time: it returns a singleton list containing its whole first argument unchanged. This is compatible with regsub.split() which also ignores empty delimiter matches. posixpath, macpath: added dirname() and normpath() (and basename() to macpath). The mainloop module (for use with stdwin) can now demultiplex input from other sources, as long as they can be polled with select(). New built-in modules -------------------- Module struct defines functions to pack/unpack values to/from strings representing binary values in native byte order. Module strop implements C versions of many functions from string (see above). Optional module fcntl defines interfaces to fcntl() and ioctl() -- UNIX only. (Not yet properly documented -- see however src/fcntl.doc.) Optional module mpz defines an interface to an altaernative long integer implementation, the GNU MPZ library. Optional module md5 uses the GNU MPZ library to calculate MD5 signatures of strings. There are also optional new modules specific to SGI machines: imageop defines some simple operations to images represented as strings; sv interfaces to the Indigo video board; cl interfaces to the (yet unreleased) compression library. New standard library modules ---------------------------- (Unfortunately the following modules are not all documented; read the sources to find out more about them!) autotest: run testall without showing any output unless it differs from the expected output bisect: use bisection to insert or find an item in a sorted list colorsys: defines conversions between various color systems (e.g. RGB <-> YUV) nntplib: a client interface to NNTP servers pipes: utility to construct pipeline from templates, e.g. for conversion from one file format to another using several utilities. regsub: contains three functions that are more or less compatible with awk functions of the same name: sub() and gsub() do string substitution, split() splits a string using a regular expression to define how separators are define. test_types: test operations on the built-in types of Python toaiff: convert various audio file formats to AIFF format tzparse: parse the TZ environment parameter (this may be less general than it could be, let me know if you fix it). (Note that the obsolete module "path" no longer exists.) New SGI-specific library modules -------------------------------- CL: constants for use with the built-in compression library interface (cl) Queue: a multi-producer, multi-consumer queue class implemented for use with the built-in thread module SOCKET: constants for use with built-in module socket, e.g. to set/get socket options. This is SGI-specific because the constants to be passed are system-dependent. You can generate a version for your own system by running the script demo/scripts/h2py.py with /usr/include/sys/socket.h as input. cddb: interface to the database used the the CD player torgb: convert various image file types to rgb format (requires pbmplus) New demos --------- There's an experimental interface to define Sun RPC clients and servers in demo/rpc. There's a collection of interfaces to WWW, WAIS and Gopher (both Python classes and program providing a user interface) in demo/www. This includes a program texi2html.py which converts texinfo files to HTML files (the format used hy WWW). The ibrowse demo has moved from demo/stdwin/ibrowse to demo/ibrowse. For SGI systems, there's a whole collection of programs and classes that make use of the Indigo video board in demo/sgi/{sv,video}. This represents a significant amount of work that we're giving away! There are demos "rsa" and "md5test" that exercise the mpz and md5 modules, respectively. The rsa demo is a complete implementation of the RSA public-key cryptosystem! A bunch of games and examples submitted by Stoffel Erasmus have been included in demo/stoffel. There are miscellaneous new files in some existing demo subdirectories: classes/bitvec.py, scripts/{fixps,methfix}.py, sgi/al/cmpaf.py, sockets/{mcast,gopher}.py. There are also many minor changes to existing files, but I'm too lazy to run a diff and note the differences -- you can do this yourself if you save the old distribution's demos. One highlight: the stdwin/python.py demo is much improved! Changes to the documentation ---------------------------- The LaTeX source for the library uses different macros to enable it to be converted to texinfo, and from there to INFO or HTML format so it can be browsed as a hypertext. The net result is that you can now read the Python library documentation in Emacs info mode! Changes to the source code that affect C extension writers ---------------------------------------------------------- The function strdup() no longer exists (it was used only in one places and is somewhat of a a portability problem sice some systems have the same function in their C library. The functions NEW() and RENEW() allocate one spare byte to guard against a NULL return from malloc(0) being taken for an error, but this should not be relied upon. ================================== ==> NEWS FOR RELEASE 0.9.7beta <== ================================== Changes to the language proper ------------------------------ User-defined classes can now implement operations invoked through special syntax, such as x[i] or `x` by defining methods named __getitem__(self, i) or __repr__(self), etc. Changes to the build process ---------------------------- Instead of extensive manual editing of the Makefile to select compile-time options, you can now run a Configure.py script. The Makefile as distributed builds a minimal interpreter sufficient to run Configure.py. See also misc/BUILD The Makefile now includes more "utility" targets, e.g. install and tags/TAGS Using the provided strtod.c and strtol.c are now separate options, as on the Sun the provided strtod.c dumps core :-( The regex module is now an option chosen by the Makefile, since some (old) C compilers choke on regexpr.c Changes affecting portability ----------------------------- You need STDWIN version 0.9.7 (released 30 June 1992) for the stdwin interface Dynamic loading is now supported for Sun (and other non-COFF systems) throug dld-3.2.3, as well as for SGI (a new version of Jack Jansen's DL is out, 1.4) The system-dependent code for the use of the select() system call is moved to one file: myselect.h Thanks to Jaap Vermeulen, the code should now port cleanly to the SEQUENT Changes to the interpreter interface ------------------------------------ The interpretation of $PYTHONPATH in the environment is different: it is inserted in front of the default path instead of overriding it Changes to existing built-in functions and methods -------------------------------------------------- List objects now support an optional argument to their sort() method, which is a comparison function similar to qsort(3) in C File objects now have a method fileno(), used by the new select module (see below) New built-in function --------------------- coerce(x, y): take two numbers and return a tuple containing them both converted to a common type Changes to built-in modules --------------------------- sys: fixed core dumps in settrace() and setprofile() socket: added socket methods setsockopt() and getsockopt(); and fileno(), used by the new select module (see below) stdwin: added fileno() == connectionnumber(), in support of new module select (see below) posix: added get{eg,eu,g,u}id(); waitpid() is now a separate function. gl: added qgetfd() fl: added several new functions, fixed several obscure bugs, adapted to FORMS 2.1 Changes to standard modules --------------------------- posixpath: changed implementation of ismount() string: atoi() no longer mistakes leading zero for octal number ... New built-in modules -------------------- Modules marked "dynamic only" are not configured at compile time but can be loaded dynamically. You need to turn on the DL or DLD option in the Makefile for support dynamic loading of modules (this requires external code). select: interfaces to the BSD select() system call dbm: interfaces to the (new) dbm library (dynamic only) nis: interfaces to some NIS functions (aka yellow pages) thread: limited form of multiple threads (sgi only) audioop: operations useful for audio programs, e.g. u-LAW and ADPCM coding (dynamic only) cd: interface to Indigo SCSI CDROM player audio library (sgi only) jpeg: read files in JPEG format (dynamic only, sgi only; needs external code) imgfile: read SGI image files (dynamic only, sgi only) sunaudiodev: interface to sun's /dev/audio (dynamic only, sun only) sv: interface to Indigo video library (sgi only) pc: a minimal set of MS-DOS interfaces (MS-DOS only) rotor: encryption, by Lance Ellinghouse (dynamic only) New standard modules -------------------- Not all these modules are documented. Read the source: lib/<modulename>.py. Sometimes a file lib/<modulename>.doc contains additional documentation. imghdr: recognizes image file headers sndhdr: recognizes sound file headers profile: print run-time statistics of Python code readcd, cdplayer: companion modules for built-in module cd (sgi only) emacs: interface to Emacs using py-connect.el (see below). SOCKET: symbolic constant definitions for socket options SUNAUDIODEV: symbolic constant definitions for sunaudiodef (sun only) SV: symbolic constat definitions for sv (sgi only) CD: symbolic constat definitions for cd (sgi only) New demos --------- scripts/pp.py: execute Python as a filter with a Perl-like command line interface classes/: examples using the new class features threads/: examples using the new thread module sgi/cd/: examples using the new cd module Changes to the documentation ---------------------------- The last-minute syntax changes of release 0.9.6 are now reflected everywhere in the manuals The reference manual has a new section (3.2) on implementing new kinds of numbers, sequences or mappings with user classes Classes are now treated extensively in the tutorial (chapter 9) Slightly restructured the system-dependent chapters of the library manual The file misc/EXTENDING incorporates documentation for mkvalue() and a new section on error handling The files misc/CLASSES and misc/ERRORS are no longer necessary The doc/Makefile now creates PostScript files automatically Miscellaneous changes --------------------- Incorporated Tim Peters' changes to python-mode.el, it's now version 1.06 A python/Emacs bridge (provided by Terrence M. Brannon) lets a Python program running in an Emacs buffer execute Emacs lisp code. The necessary Python code is in lib/emacs.py. The Emacs code is misc/py-connect.el (it needs some external Emacs lisp code) Changes to the source code that affect C extension writers ---------------------------------------------------------- New service function mkvalue() to construct a Python object from C values according to a "format" string a la getargs() Most functions from pythonmain.c moved to new pythonrun.c which is in libpython.a. This should make embedded versions of Python easier ceval.h is split in eval.h (which needs compile.h and only declares eval_code) and ceval.h (which doesn't need compile.hand declares the rest) ceval.h defines macros BGN_SAVE / END_SAVE for use with threads (to improve the parallellism of multi-threaded programs by letting other Python code run when a blocking system call or something similar is made) In structmember.[ch], new member types BYTE, CHAR and unsigned variants have been added New file xxmodule.c is a template for new extension modules. To: python-list Subject: Python 0.9.8 released From: Guido.van.Rossum@cwi.nl X-Organization: CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Sat, 09 Jan 1993 21:31:04 +0100 Sender: guido I have finally released the long-awaited Python version 0.9.8. Boy has it been a heavy delivery! But the baby is healthy as can be... You can ftp it from the following sites: Location Site IP address Directory Amsterdam ftp.cwi.nl 192.16.184.180 /pub/python U.S.A. wuarchive.wustl.edu 128.252.135.4 /pub The filename is python0.9.8.tar.Z. (Note the changed directory name on ftp.cwi.nl!) There's also a file containing PostScript of the documentation (tutorial, reference, library): pythondoc-ps0.9.8.tar.Z. I'm sorry, there are no Mac or PC versions yet. The version on wuarchive is likely to evaporate some time after it is installed; I will try to make sure that the version on ftp.cwi.nl is always there. You are invited to copy these files to other ftp archives to which you have access. Below is an exhaustive list of changes since 0.9.6 (which most of you are probably still using). If you wonder what happened to 0.9.7: there was a 0.9.7beta, which was a little rough, and instead of polishing it up a bit, I went ahead and made many more changes, so eventually I felt myself forced to call it 0.9.8. If you experience any kind of trouble with building or using 0.9.8, please mail a short description giving as much detail as possible about what system and configuration you are using and what kind of error messages you get, either to the list, or to me (if you fear it might be your own fault and don't want to be embarrassed). In all cases I will try to do something about it, providing either a work-around or patch. --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> ============================== ==> NEWS FOR RELEASE 0.9.8 <== ============================== I claim no completeness here, but I've tried my best to scan the log files throughout my source tree for interesting bits of news. A more complete account of the changes is to be found in the various ChangeLog files. See also "News for release 0.9.7beta" below if you're still using release 0.9.6, and the file HISTORY if you have an even older release. --Guido Changes to the language proper ------------------------------ There's only one big change: the conformance checking for function argument lists (of user-defined functions only) is stricter. Earlier, you could get away with the following: (a) define a function of one argument and call it with any number of arguments; if the actual argument count wasn't one, the function would receive a tuple containing the arguments arguments (an empty tuple if there were none). (b) define a function of two arguments, and call it with more than two arguments; if there were more than two arguments, the second argument would be passed as a tuple containing the second and further actual arguments. (Note that an argument (formal or actual) that is a tuple is counted as one; these rules don't apply inside such tuples, only at the top level of the argument list.) Case (a) was needed to accommodate variable-length argument lists; there is now an explicit "varargs" feature (precede the last argument with a '*'). Case (b) was needed for compatibility with old class definitions: up to release 0.9.4 a method with more than one argument had to be declared as "def meth(self, (arg1, arg2, ...)): ...". Version 0.9.6 provide better ways to handle both casees, bot provided backward compatibility; version 0.9.8 retracts the compatibility hacks since they also cause confusing behavior if a function is called with the wrong number of arguments. There's a script that helps converting classes that still rely on (b), provided their methods' first argument is called "self": demo/scripts/methfix.py. If this change breaks lots of code you have developed locally, try #defining COMPAT_HACKS in ceval.c. (There's a third compatibility hack, which is the reverse of (a): if a function is defined with two or more arguments, and called with a single argument that is a tuple with just as many arguments, the items of this tuple will be used as the arguments. Although this can (and should!) be done using the built-in function apply() instead, it isn't withdrawn yet.) One minor change: comparing instance methods works like expected, so that if x is an instance of a user-defined class and has a method m, then (x.m==x.m) yields 1. The following was already present in 0.9.7beta, but not explicitly mentioned in the NEWS file: user-defined classes can now define types that behave in almost allrespects like numbers. See demo/classes/Rat.py for a simple example. Changes to the build process ---------------------------- The Configure.py script and the Makefile has been made somewhat more bullet-proof, after reports of (minor) trouble on certain platforms. There is now a script to patch Makefile and config.c to add a new optional built-in module: Addmodule.sh. Read the script before using! Useing Addmodule.sh, all optional modules can now be configured at compile time using Configure.py, so there are no modules left that require dynamic loading. The Makefile has been fixed to make it easier to use with the VPATH feature of some Make versions (e.g. SunOS). Changes affecting portability ----------------------------- Several minor portability problems have been solved, e.g. "malloc.h" has been renamed to "mymalloc.h", "strdup.c" is no longer used, and the system now tolerates malloc(0) returning 0. For dynamic loading on the SGI, Jack Jansen's dl 1.6 is now distributed with Python. This solves several minor problems, in particular scripts invoked using #! can now use dynamic loading. Changes to the interpreter interface ------------------------------------ On popular demand, there's finally a "profile" feature for interactive use of the interpreter. If the environment variable $PYTHONSTARTUP is set to the name of an existing file, Python statements in this file are executed when the interpreter is started in interactive mode. There is a new clean-up mechanism, complementing try...finally: if you assign a function object to sys.exitfunc, it will be called when Python exits or receives a SIGTERM or SIGHUP signal. The interpreter is now generally assumed to live in /usr/local/bin/python (as opposed to /usr/local/python). The script demo/scripts/fixps.py will update old scripts in place (you can easily modify it to do other similar changes). Most I/O that uses sys.stdin/stdout/stderr will now use any object assigned to those names as long as the object supports readline() or write() methods. The parser stack has been increased to 500 to accommodate more complicated expressions (7 levels used to be the practical maximum, it's now about 38). The limit on the size of the *run-time* stack has completely been removed -- this means that tuple or list displays can contain any number of elements (formerly more than 50 would crash the interpreter). Changes to existing built-in functions and methods -------------------------------------------------- The built-in functions int(), long(), float(), oct() and hex() now also apply to class instalces that define corresponding methods (__int__ etc.). New built-in functions ---------------------- The new functions str() and repr() convert any object to a string. The function repr(x) is in all respects equivalent to `x` -- some people prefer a function for this. The function str(x) does the same except if x is already a string -- then it returns x unchanged (repr(x) adds quotes and escapes "funny" characters as octal escapes). The new function cmp(x, y) returns -1 if x<y, 0 if x==y, 1 if x>y. Changes to general built-in modules ----------------------------------- The time module's functions are more general: time() returns a floating point number and sleep() accepts one. Their accuracies depends on the precision of the system clock. Millisleep is no longer needed (although it still exists for now), but millitimer is still needed since on some systems wall clock time is only available with seconds precision, while a source of more precise time exists that isn't synchronized with the wall clock. (On UNIX systems that support the BSD gettimeofday() function, time.time() is as time.millitimer().) The string representation of a file object now includes an address: '<file 'filename', mode 'r' at #######>' where ###### is a hex number (the object's address) to make it unique. New functions added to posix: nice(), setpgrp(), and if your system supports them: setsid(), setpgid(), tcgetpgrp(), tcsetpgrp(). Improvements to the socket module: socket objects have new methods getpeername() and getsockname(), and the {get,set}sockopt methods can now get/set any kind of option using strings built with the new struct module. And there's a new function fromfd() which creates a socket object given a file descriptor (useful for servers started by inetd, which have a socket connected to stdin and stdout). Changes to SGI-specific built-in modules ---------------------------------------- The FORMS library interface (fl) now requires FORMS 2.1a. Some new functions have been added and some bugs have been fixed. Additions to al (audio library interface): added getname(), getdefault() and getminmax(). The gl modules doesn't call "foreground()" when initialized (this caused some problems) like it dit in 0.9.7beta (but not before). There's a new gl function 'gversion() which returns a version string. The interface to sv (Indigo video interface) has totally changed. (Sorry, still no documentation, but see the examples in demo/sgi/{sv,video}.) Changes to standard library modules ----------------------------------- Most functions in module string are now much faster: they're actually implemented in C. The module containing the C versions is called "strop" but you should still import "string" since strop doesn't provide all the interfaces defined in string (and strop may be renamed to string when it is complete in a future release). string.index() now accepts an optional third argument giving an index where to start searching in the first argument, so you can find second and further occurrences (this is similar to the regular expression functions in regex). The definition of what string.splitfields(anything, '') should return is changed for the last time: it returns a singleton list containing its whole first argument unchanged. This is compatible with regsub.split() which also ignores empty delimiter matches. posixpath, macpath: added dirname() and normpath() (and basename() to macpath). The mainloop module (for use with stdwin) can now demultiplex input from other sources, as long as they can be polled with select(). New built-in modules -------------------- Module struct defines functions to pack/unpack values to/from strings representing binary values in native byte order. Module strop implements C versions of many functions from string (see above). Optional module fcntl defines interfaces to fcntl() and ioctl() -- UNIX only. (Not yet properly documented -- see however src/fcntl.doc.) Optional module mpz defines an interface to an altaernative long integer implementation, the GNU MPZ library. Optional module md5 uses the GNU MPZ library to calculate MD5 signatures of strings. There are also optional new modules specific to SGI machines: imageop defines some simple operations to images represented as strings; sv interfaces to the Indigo video board; cl interfaces to the (yet unreleased) compression library. New standard library modules ---------------------------- (Unfortunately the following modules are not all documented; read the sources to find out more about them!) autotest: run testall without showing any output unless it differs from the expected output bisect: use bisection to insert or find an item in a sorted list colorsys: defines conversions between various color systems (e.g. RGB <-> YUV) nntplib: a client interface to NNTP servers pipes: utility to construct pipeline from templates, e.g. for conversion from one file format to another using several utilities. regsub: contains three functions that are more or less compatible with awk functions of the same name: sub() and gsub() do string substitution, split() splits a string using a regular expression to define how separators are define. test_types: test operations on the built-in types of Python toaiff: convert various audio file formats to AIFF format tzparse: parse the TZ environment parameter (this may be less general than it could be, let me know if you fix it). (Note that the obsolete module "path" no longer exists.) New SGI-specific library modules -------------------------------- CL: constants for use with the built-in compression library interface (cl) Queue: a multi-producer, multi-consumer queue class implemented for use with the built-in thread module SOCKET: constants for use with built-in module socket, e.g. to set/get socket options. This is SGI-specific because the constants to be passed are system-dependent. You can generate a version for your own system by running the script demo/scripts/h2py.py with /usr/include/sys/socket.h as input. cddb: interface to the database used the the CD player torgb: convert various image file types to rgb format (requires pbmplus) New demos --------- There's an experimental interface to define Sun RPC clients and servers in demo/rpc. There's a collection of interfaces to WWW, WAIS and Gopher (both Python classes and program providing a user interface) in demo/www. This includes a program texi2html.py which converts texinfo files to HTML files (the format used hy WWW). The ibrowse demo has moved from demo/stdwin/ibrowse to demo/ibrowse. For SGI systems, there's a whole collection of programs and classes that make use of the Indigo video board in demo/sgi/{sv,video}. This represents a significant amount of work that we're giving away! There are demos "rsa" and "md5test" that exercise the mpz and md5 modules, respectively. The rsa demo is a complete implementation of the RSA public-key cryptosystem! A bunch of games and examples submitted by Stoffel Erasmus have been included in demo/stoffel. There are miscellaneous new files in some existing demo subdirectories: classes/bitvec.py, scripts/{fixps,methfix}.py, sgi/al/cmpaf.py, sockets/{mcast,gopher}.py. There are also many minor changes to existing files, but I'm too lazy to run a diff and note the differences -- you can do this yourself if you save the old distribution's demos. One highlight: the stdwin/python.py demo is much improved! Changes to the documentation ---------------------------- The LaTeX source for the library uses different macros to enable it to be converted to texinfo, and from there to INFO or HTML format so it can be browsed as a hypertext. The net result is that you can now read the Python library documentation in Emacs info mode! Changes to the source code that affect C extension writers ---------------------------------------------------------- The function strdup() no longer exists (it was used only in one places and is somewhat of a a portability problem sice some systems have the same function in their C library. The functions NEW() and RENEW() allocate one spare byte to guard against a NULL return from malloc(0) being taken for an error, but this should not be relied upon. ================================== ==> NEWS FOR RELEASE 0.9.7beta <== ================================== Changes to the language proper ------------------------------ User-defined classes can now implement operations invoked through special syntax, such as x[i] or `x` by defining methods named __getitem__(self, i) or __repr__(self), etc. Changes to the build process ---------------------------- Instead of extensive manual editing of the Makefile to select compile-time options, you can now run a Configure.py script. The Makefile as distributed builds a minimal interpreter sufficient to run Configure.py. See also misc/BUILD The Makefile now includes more "utility" targets, e.g. install and tags/TAGS Using the provided strtod.c and strtol.c are now separate options, as on the Sun the provided strtod.c dumps core :-( The regex module is now an option chosen by the Makefile, since some (old) C compilers choke on regexpr.c Changes affecting portability ----------------------------- You need STDWIN version 0.9.7 (released 30 June 1992) for the stdwin interface Dynamic loading is now supported for Sun (and other non-COFF systems) throug dld-3.2.3, as well as for SGI (a new version of Jack Jansen's DL is out, 1.4) The system-dependent code for the use of the select() system call is moved to one file: myselect.h Thanks to Jaap Vermeulen, the code should now port cleanly to the SEQUENT Changes to the interpreter interface ------------------------------------ The interpretation of $PYTHONPATH in the environment is different: it is inserted in front of the default path instead of overriding it Changes to existing built-in functions and methods -------------------------------------------------- List objects now support an optional argument to their sort() method, which is a comparison function similar to qsort(3) in C File objects now have a method fileno(), used by the new select module (see below) New built-in function --------------------- coerce(x, y): take two numbers and return a tuple containing them both converted to a common type Changes to built-in modules --------------------------- sys: fixed core dumps in settrace() and setprofile() socket: added socket methods setsockopt() and getsockopt(); and fileno(), used by the new select module (see below) stdwin: added fileno() == connectionnumber(), in support of new module select (see below) posix: added get{eg,eu,g,u}id(); waitpid() is now a separate function. gl: added qgetfd() fl: added several new functions, fixed several obscure bugs, adapted to FORMS 2.1 Changes to standard modules --------------------------- posixpath: changed implementation of ismount() string: atoi() no longer mistakes leading zero for octal number ... New built-in modules -------------------- Modules marked "dynamic only" are not configured at compile time but can be loaded dynamically. You need to turn on the DL or DLD option in the Makefile for support dynamic loading of modules (this requires external code). select: interfaces to the BSD select() system call dbm: interfaces to the (new) dbm library (dynamic only) nis: interfaces to some NIS functions (aka yellow pages) thread: limited form of multiple threads (sgi only) audioop: operations useful for audio programs, e.g. u-LAW and ADPCM coding (dynamic only) cd: interface to Indigo SCSI CDROM player audio library (sgi only) jpeg: read files in JPEG format (dynamic only, sgi only; needs external code) imgfile: read SGI image files (dynamic only, sgi only) sunaudiodev: interface to sun's /dev/audio (dynamic only, sun only) sv: interface to Indigo video library (sgi only) pc: a minimal set of MS-DOS interfaces (MS-DOS only) rotor: encryption, by Lance Ellinghouse (dynamic only) New standard modules -------------------- Not all these modules are documented. Read the source: lib/<modulename>.py. Sometimes a file lib/<modulename>.doc contains additional documentation. imghdr: recognizes image file headers sndhdr: recognizes sound file headers profile: print run-time statistics of Python code readcd, cdplayer: companion modules for built-in module cd (sgi only) emacs: interface to Emacs using py-connect.el (see below). SOCKET: symbolic constant definitions for socket options SUNAUDIODEV: symbolic constant definitions for sunaudiodef (sun only) SV: symbolic constat definitions for sv (sgi only) CD: symbolic constat definitions for cd (sgi only) New demos --------- scripts/pp.py: execute Python as a filter with a Perl-like command line interface classes/: examples using the new class features threads/: examples using the new thread module sgi/cd/: examples using the new cd module Changes to the documentation ---------------------------- The last-minute syntax changes of release 0.9.6 are now reflected everywhere in the manuals The reference manual has a new section (3.2) on implementing new kinds of numbers, sequences or mappings with user classes Classes are now treated extensively in the tutorial (chapter 9) Slightly restructured the system-dependent chapters of the library manual The file misc/EXTENDING incorporates documentation for mkvalue() and a new section on error handling The files misc/CLASSES and misc/ERRORS are no longer necessary The doc/Makefile now creates PostScript files automatically Miscellaneous changes --------------------- Incorporated Tim Peters' changes to python-mode.el, it's now version 1.06 A python/Emacs bridge (provided by Terrence M. Brannon) lets a Python program running in an Emacs buffer execute Emacs lisp code. The necessary Python code is in lib/emacs.py. The Emacs code is misc/py-connect.el (it needs some external Emacs lisp code) Changes to the source code that affect C extension writers ---------------------------------------------------------- New service function mkvalue() to construct a Python object from C values according to a "format" string a la getargs() Most functions from pythonmain.c moved to new pythonrun.c which is in libpython.a. This should make embedded versions of Python easier ceval.h is split in eval.h (which needs compile.h and only declares eval_code) and ceval.h (which doesn't need compile.hand declares the rest) ceval.h defines macros BGN_SAVE / END_SAVE for use with threads (to improve the parallellism of multi-threaded programs by letting other Python code run when a blocking system call or something similar is made) In structmember.[ch], new member types BYTE, CHAR and unsigned variants have been added New file xxmodule.c is a template for new extension modules. Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA14861 (5.65b/3.6/CWI-Amsterdam); Tue, 12 Jan 1993 14:03:42 +0100 Received: by voorn.cwi.nl with SMTP id AA10677 (5.65b/3.5/CWI-Amsterdam); Tue, 12 Jan 1993 14:03:42 +0100 Message-Id: <9301121303.AA10677.guido@voorn.cwi.nl> To: python-list@cwi.nl Subject: Mac Python 0.9.8 ready From: Guido.van.Rossum@cwi.nl X-Organization: CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Tue, 12 Jan 1993 14:03:41 +0100 Sender: Guido.van.Rossum@cwi.nl To all ye Macintosh owners / Python lovers! A Macintosh binary of a Python interpreter is now available. Site IP address Directory ftp.cwi.nl 192.16.184.180 /pub/python wuarchive.wustl.edu 128.252.135.4 /pub The filename is MacPython0.9.8.hqx. This is a binhexed stuffit 1.5.1 archive of the application file only. In order to get the Python library (highly recommended :-) you still need to fetch and extract the source distribution (python0.9.8.tar.Z) and copy python/lib/*.py to your Macintosh. The default search path is [':', ':lib', ':demo']. The following built-in modules are present: sys, builtin, marshal, struct, time, math, strop, time, mac, regex, stdwin, audioop, imageop, rotor. A new feature which isn't documented (yet): if a file PythonStartup exists (in the current folder or in the system folder) it will be executed when the interpreter is started interactively. As in previous versions, if a TEXT file has owner PYTH (the same as the Python application), opening it will launch the Python interpreter and execute the file as a script. And in case you wondered: the application's icon is supposed to represent the 16-ton weight appearing in some Monty Python sketches :-) --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Fri, 15 Jan 1993 22:59:47 +0100 Replied: python-list@cwi.nl Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA07316 (5.65b/3.6/CWI-Amsterdam); Fri, 15 Jan 1993 20:45:56 +0100 From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: python-list@cwi.nl Subject: marshall type but builds stringobj?? Date: Fri, 15 Jan 93 11:45:06 PST Message-Id: <9301151145.aa24928@hermix.markv.com> Has anyone put together a 'marshall' type module that instead of dumping everything to a file, it would create a stringobj that contained the information??? I would like to be able to create a stringobj that contains the same information as when you do a marshal.dump()... This will allow me to send PYTHON objects across networks! :) Lance Ellinghouse lance@markv.com Replied: Fri, 15 Jan 1993 22:55:59 +0100 Replied: postmaster@isye.gatech.edu Received: by charon.cwi.nl id AA07318 (5.65b/3.6/CWI-Amsterdam); Fri, 15 Jan 1993 20:45:56 +0100 Date: Fri, 15 Jan 1993 20:45:56 +0100 From: MAILER-DAEMON@cwi.nl Subject: Returned mail: Deferred: Host Name Lookup Failure Message-Id: <9301151945.AA07318.MAILER-DAEMON@charon.cwi.nl> To: owner-python-list@cwi.nl ----- Transcript of session follows ----- While talking to isye.gatech.edu: >>> RCPT To:<mondomon@isye.gatech.edu> <<< 550 <mondomon@isye.gatech.edu>... User unknown 550 "Allan Stuart Mackinnon Jr." <mondomon@isye.gatech.edu>... User unknown ----- Unsent message follows ----- Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA07316 (5.65b/3.6/CWI-Amsterdam); Fri, 15 Jan 1993 20:45:56 +0100 From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: python-list@cwi.nl Subject: marshall type but builds stringobj?? Date: Fri, 15 Jan 93 11:45:06 PST Message-Id: <9301151145.aa24928@hermix.markv.com> Has anyone put together a 'marshall' type module that instead of dumping everything to a file, it would create a stringobj that contained the information??? I would like to be able to create a stringobj that contains the same information as when you do a marshal.dump()... This will allow me to send PYTHON objects across networks! :) Lance Ellinghouse lance@markv.com To: postmaster@isye.gatech.edu Subject: What happened to Allan Stuart Mackinnon Jr. <mondomon@isye.gatech.edu> In-reply-to: Your message of "Fri, 15 Jan 1993 20:45:56 MET." <9301151945.AA07318.MAILER-DAEMON@charon.cwi.nl> From: Guido.van.Rossum@cwi.nl X-Organization: CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Fri, 15 Jan 1993 22:55:57 +0100 Sender: guido Hello, I'm maintaining a mailing list which contains the address "Allan Stuart Mackinnon Jr." <mondomon@isye.gatech.edu> The latest mail to this address fails (see below). What has happened? Is there a new address, or should I just remove the address from my mailing list? Thank you for your time, --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> > ----- Transcript of session follows ----- >While talking to isye.gatech.edu: >>>> RCPT To:<mondomon@isye.gatech.edu> ><<< 550 <mondomon@isye.gatech.edu>... User unknown >550 "Allan Stuart Mackinnon Jr." <mondomon@isye.gatech.edu>... User unknown > > ----- Unsent message follows ----- >Received: from hermix.markv.com by charon.cwi.nl with SMTP > id AA07316 (5.65b/3.6/CWI-Amsterdam); Fri, 15 Jan 1993 20:45:56 +0100 >From: Lance Ellinghouse <lance@markv.com> >X-Mailer: SCO System V Mail (version 3.2) >To: python-list@cwi.nl >Subject: marshall type but builds stringobj?? >Date: Fri, 15 Jan 93 11:45:06 PST >Message-Id: <9301151145.aa24928@hermix.markv.com> > >Has anyone put together a 'marshall' type module that instead >of dumping everything to a file, it would create a stringobj that >contained the information??? > >I would like to be able to create a stringobj that contains the same >information as when you do a marshal.dump()... This will allow me >to send PYTHON objects across networks! :) > >Lance Ellinghouse >lance@markv.com --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> To: python-list@cwi.nl Subject: Re: marshall type but builds stringobj?? In-reply-to: Your message of "Fri, 15 Jan 1993 11:45:06 MET." <9301151145.aa24928@hermix.markv.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Fri, 15 Jan 1993 22:59:46 +0100 Sender: guido Lance Ellinghouse: >Has anyone put together a 'marshall' type module that instead >of dumping everything to a file, it would create a stringobj that >contained the information??? > >I would like to be able to create a stringobj that contains the same >information as when you do a marshal.dump()... This will allow me >to send PYTHON objects across networks! :) You can already send Python objects as strings across networks using repr() or `` and eval(), but you're right that marshal would be more efficient. (Though not more general -- the same objects for which eval(`x`) fails also cannot be load()ed by marshal.) This has been asked so many times now that I think I'll try to do something about it... --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA12164 (5.65b/3.6/CWI-Amsterdam); Fri, 15 Jan 1993 22:59:47 +0100 Received: by voorn.cwi.nl with SMTP id AA21221 (5.65b/3.5/CWI-Amsterdam); Fri, 15 Jan 1993 22:59:47 +0100 Message-Id: <9301152159.AA21221.guido@voorn.cwi.nl> To: python-list@cwi.nl Subject: Re: marshall type but builds stringobj?? In-Reply-To: Your message of "Fri, 15 Jan 1993 11:45:06 MET." <9301151145.aa24928@hermix.markv.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Fri, 15 Jan 1993 22:59:46 +0100 Sender: Guido.van.Rossum@cwi.nl Lance Ellinghouse: >Has anyone put together a 'marshall' type module that instead >of dumping everything to a file, it would create a stringobj that >contained the information??? > >I would like to be able to create a stringobj that contains the same >information as when you do a marshal.dump()... This will allow me >to send PYTHON objects across networks! :) You can already send Python objects as strings across networks using repr() or `` and eval(), but you're right that marshal would be more efficient. (Though not more general -- the same objects for which eval(`x`) fails also cannot be load()ed by marshal.) This has been asked so many times now that I think I'll try to do something about it... --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Sat, 16 Jan 1993 00:29:00 +0100 Replied: python-list@cwi.nl Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA16966 (5.65b/3.6/CWI-Amsterdam); Sat, 16 Jan 1993 00:15:24 +0100 From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: python-list@cwi.nl Subject: Re: marshall type but builds stringobj?? Date: Fri, 15 Jan 93 15:15:06 PST Message-Id: <9301151515.aa13003@hermix.markv.com> In-Reply-To: Your message of "Fri, 15 Jan 1993 11:45:06 MET." <9301151145.aa24928@hermix.markv.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Fri, 15 Jan 1993 22:59:46 +0100 Sender: Guido.van.Rossum@cwi.nl Status: R Guido: >Lance Ellinghouse: >>Has anyone put together a 'marshall' type module that instead >>of dumping everything to a file, it would create a stringobj that >>contained the information??? >> >>I would like to be able to create a stringobj that contains the same >>information as when you do a marshal.dump()... This will allow me >>to send PYTHON objects across networks! :) > You can already send Python objects as strings across networks using > repr() or `` and eval(), but you're right that marshal would be more > efficient. (Though not more general -- the same objects for which > eval(`x`) fails also cannot be load()ed by marshal.) This may be true, but You cannot send the following easily using repr() or `` or eval(): (0,'This is a test',func) Where func is a code object that should be sent and executed on the remote machine (where 'func' did NOT exist on the remote machine). > This has been asked so many times now that I think I'll try to do > something about it... Great! Lance Ellinghouse lance@markv.com To: python-list@cwi.nl Subject: Re: marshall type but builds stringobj?? In-reply-to: Your message of "Fri, 15 Jan 1993 15:15:06 MET." <9301151515.aa13003@hermix.markv.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Sat, 16 Jan 1993 00:28:52 +0100 Sender: guido me: >> You can already send Python objects as strings across networks using >> repr() or `` and eval(), but you're right that marshal would be more >> efficient. (Though not more general -- the same objects for which >> eval(`x`) fails also cannot be load()ed by marshal.) Lance: >This may be true, but You cannot send the following easily using repr() >or `` or eval(): > > (0,'This is a test',func) > >Where func is a code object that should be sent and executed on the >remote machine (where 'func' did NOT exist on the remote machine). And indeed you can't marshal function objects either. The reason is that a function object contains a reference to the module in which it is declared, because it *may* need global variables there. The same module may not exist at the remote end, and even if it exists the effect would not be the same, since the values of the global variables in that module may differ. This is not likely to change. Note that even if the function *doesn't* reference global variables it still contains a pointer to the module, since the parser isn't powerful enough to detect this. If you really need to pass a function to a remote machine, you are better off sending the function's source code. "Code objects", the internal "compiled" form of Python code, can be marshalled, however there is no way to call a code object (the implementation of "import" uses code objects). (Maybe there should be a way?) --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from dahlia.cwi.nl by charon.cwi.nl with SMTP id AA19458 (5.65b/3.6/CWI-Amsterdam); Sat, 16 Jan 1993 00:28:54 +0100 Received: by dahlia.cwi.nl with SMTP id AA09693 (5.65b/3.5/CWI-Amsterdam); Sat, 16 Jan 1993 00:28:53 +0100 Message-Id: <9301152328.AA09693.guido@dahlia.cwi.nl> To: python-list@cwi.nl Subject: Re: marshall type but builds stringobj?? In-Reply-To: Your message of "Fri, 15 Jan 1993 15:15:06 MET." <9301151515.aa13003@hermix.markv.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Sat, 16 Jan 1993 00:28:52 +0100 Sender: Guido.van.Rossum@cwi.nl me: >> You can already send Python objects as strings across networks using >> repr() or `` and eval(), but you're right that marshal would be more >> efficient. (Though not more general -- the same objects for which >> eval(`x`) fails also cannot be load()ed by marshal.) Lance: >This may be true, but You cannot send the following easily using repr() >or `` or eval(): > > (0,'This is a test',func) > >Where func is a code object that should be sent and executed on the >remote machine (where 'func' did NOT exist on the remote machine). And indeed you can't marshal function objects either. The reason is that a function object contains a reference to the module in which it is declared, because it *may* need global variables there. The same module may not exist at the remote end, and even if it exists the effect would not be the same, since the values of the global variables in that module may differ. This is not likely to change. Note that even if the function *doesn't* reference global variables it still contains a pointer to the module, since the parser isn't powerful enough to detect this. If you really need to pass a function to a remote machine, you are better off sending the function's source code. "Code objects", the internal "compiled" form of Python code, can be marshalled, however there is no way to call a code object (the implementation of "import" uses code objects). (Maybe there should be a way?) --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA23827 (5.65b/3.6/CWI-Amsterdam); Mon, 18 Jan 1993 10:53:50 +0100 Received: by voorn.cwi.nl with SMTP id AA25242 (5.65b/3.5/CWI-Amsterdam); Mon, 18 Jan 1993 10:53:50 +0100 Message-Id: <9301180953.AA25242.guido@voorn.cwi.nl> To: python-list@cwi.nl Subject: bugfix for longobject.c (all versions) From: Guido.van.Rossum@cwi.nl X-Organization: CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Mon, 18 Jan 1993 10:53:49 +0100 Sender: Guido.van.Rossum@cwi.nl I've been told that there's a bug in the comparison of negative long integers. It's a record-breaking bug, since it has existed since the very first implementation of long ints! So maybe it isn't of critical importance, but since I've just found a 2-line fix I don't want to withhold that from y'all. You don't need to test whether you have the bug -- I'm sure you have it, but in case you're interested, it turns out that -2L compares greater than -1L ... Apply this patch to longobject and it's fixed... (Not that you care -- or else why did nobody complain before?) =================================================================== RCS file: /ufs/guido/CVSROOT/python/src/longobject.c,v retrieving revision 1.17 diff -c -1 -r1.17 longobject.c *** 1.17 1992/09/17 17:54:47 --- longobject.c 1993/01/18 09:16:05 *************** *** 608,611 **** sign = 0; ! else sign = (int)a->ob_digit[i] - (int)b->ob_digit[i]; } --- 608,614 ---- sign = 0; ! else { sign = (int)a->ob_digit[i] - (int)b->ob_digit[i]; + if (a->ob_size < 0) + sign = -sign; + } } =================================================================== Note that this doesn't mean I'll soon bring out a new release -- 0.9.8 appears quite stable, there have been a number of problem reports but these all pertain to minor things that can be fixed by massaging the Makefile a little bit, or they are very platform-specific (hallo Jaap!). Cheers, --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA29971 (5.65b/3.8/CWI-Amsterdam); Fri, 22 Jan 1993 00:32:41 +0100 Received: by voorn.cwi.nl with SMTP id AA06986 (5.65b/3.8/CWI-Amsterdam); Fri, 22 Jan 1993 00:32:40 +0100 Message-Id: <9301212332.AA06986=guido@voorn.cwi.nl> To: python-list@cwi.nl Subject: How about an ARRAY type in Python From: se@risc3.mi.Uni-Koeln.DE (Stefan Esser) Date: Fri, 22 Jan 1993 00:32:40 +0100 Sender: Guido.van.Rossum@cwi.nl [Posting for Stefan Esser who is having trouble with mailing to the list. Anyone else have a complaint about the list recently? --Guido] Hi everybody ! Having been a long time user of Perl, I've given the just announced Python 0.9.8 a try and was surprised of the clean design and easy expandabilty of the language. But there is one thing that I'd like to see changed for performance reasons, and that is the fact, that the only array type supported is the array of characters (that is strings). I'm new to this list, so I don't know if there has been much discussion on that topic and what the results (if any) have been... Although the Python interpreter isn't fast compared to compiled languages, I'd like to use Python for a purpose where Megabytes of data have to be processed: the examination of nuclear physics spectroscopy data. There is a library I've written some time ago, which performs conversion and compression of our experimental data, but it has proven to be an annoying task to combine these access functions into useable programs performing tasks like matrix transpose or projections with typical matrix sizes of 4096*4096 elements. Python makes it (due to its exception concept) very easy to write programs with reasonable behavior in the case of runtime or operator errors, and catching exceptions in a user friendly way is the main reason for my C programs' complexity now. Now what I'd like to be able to do in Python: 1) Open existing matrix files in any of the supported formats (little/big endian 2/4 byte integer, floats, text, compressed,...) and getting information on file type and matrix dimensions [ got that already to work fine ... ] 2) Access data from these files using the slice syntax of Python. [ Quite simple if I'm going to unpack the arrays, the low level routines operate on, into lists. But reading a typical matrix file once would then mean unpacking 64 Mbyte of data into 16Mio int objects. And that's why I (think that I) need an array object class. ] 3) Assign a 1-dim array (or a 1-dim slice of a 2-dim array) to a line or column of a 2-dim array. This ought to make it possible to write a matrix transpose this way: for i in range(src.lines): dst[i][:] = src[:][i] The semantics of that operation have to be quite different from what they are on lists now! (Eg. src[:][i] is equivalent to src[i] now, if src is a list.) This may require changes to the interpreter to work (I'm not sure whether it can be easily implemented by __getitem__/__getslice__ and corresponding __setXX__ methods ? If array_ass_slice() can be made to do the right thing, then there was no need for any change to python ??). 4) Make this work not only on my special matrix file objects, but also on a general Python object that represents an array in RAM by indexing into a contigous large array, instead of as a list/tree structure. The special object of 3) can now be made a special case of this more general object. 5) Have a way to create array object instances, eg. using the following syntax: a = 0[10] # 1-dim array of 10 integers, initialized to 0 f = 1.0[10][20] # 2-dim array of 10 lines of 20 floats each, init=1.0 o = None[10] # 1-dim array of 10 objects, initialized to <None> s = ' '[100] # 100 byte string initialized to blank space s = ''[100] # ... special case: as above, but init to '\0' This array object ought (IMHO) to be represented by the following C struct: typedef struct { int mult; /* horner scheme multiplicator */ int limit; /* index range is [0 .. (limit-1)] */ } typedef struct { OB_HEAD void *data; char elemtype; /* elem_char, elem_int, elem_float, elem_obj */ char status; /* controls behaviour of slicing and assign. */ int dims; /* 0 = scalar, 1 = vector, 2 = matrix, ... */ dim_type dim[1]; /* actually repeated 'dims' times ... */ } arrayobject; A 2-dim array A of 10 lines of 20 columns of integers might then be represented by the following actual data: data = <array base> elemtype = elem_int status = ( to be specified :) dims = 2 dim[0].mult = 4 /* sizeof(int) */ dim[0].limit = 20 dim[1].mult = 20 dim[1].limit = 10 Slice and index operations only modify (a copy) of struct arrayobject, eg. A[0:2][0:4] would correspond to the same data array, but the following descriptor: data = <array base> elemtype = elem_int status = ( to be specified :) dims = 2 dim[0].mult = 4 /* sizeof(int) */ dim[0].limit = 4 dim[1].mult = 20 dim[1].limit = 2 A[1:3][2:6] would be identical, except that the data pointer would have been adjusted to point to the address of A[1][2] instead of to the base of the array. data = <array base> + (( 1 ) * dim[1].mult + 2) * dim[0].mult = <array base> + 88 elemtype = elem_int ... Further ideas on array object semantics: (This is what I need in my applications, it isn't neccessarily what the way one would like an general array object to behave. That's the reason I want to discuss this array object type ...) Assignment compatibility requires same number of (free) dimensions and same index range in each dimension. Each index (as opposed to slice) operator reduces the dimension of the resulting object by one. Given 3-dim arrays A,B of 10*20*30 elements (that is 30 per 'line'): High dimension slices containing the full range of indizes can be omitted: A[0] is interpreted as A[:][:][0] in the case of a 3-dim array. Assignment compatibility: B[:] = A[0:10][0:20][0:30] # same index ranges on both sides B[:] = A[:] # same as above in this particular case B[0:20][0] = A[0][0:20] # both got one index fixed and 20 # elements at the lowest non fixed # index B[0:2][0][0:2] = A[0][0:2][0:2] # same as above, except different # number of elements A[0][0:2][0:2] = ((1,2),(3,4)) # assignment between arrays and lists # ought to work in both directions Methods of array instances: A.__min__() min(A[0:3]) # element with min. value A.__max__() max(A{:]) # element with max. value A.__len__() len(A[:]) # number of elements A.__sum__() A[:] + B[:] # add two matrizes A.__mult__() A[:] * n # mult each elem with scalar A.__mult__() A[:] * B[:} # scalar product ... Attributes: A.dims # RO dimensions A.dim # list of limits, # highest dim first (or last ??) ??? A.elemtype # type object corresp. to elements One think I'm considering useful is, to treat (given the above definition of array A) A[0] equiv. A[0][0][0], but A[0:1] equiv. A[:][:][0:1] equiv A[:][:][0] This would make access to the undelying element object easy without need to have an index expression corresponding to the dimension of the array. (Else in case of a 4-dim array A: A[0][0][0] equiv. A[:][0][0][0] ... ... that is: an 1-dim array as opposed to the element type (eg. integer) in case of 'A' being a 3-dim array, given the above index expression). (A flag, whether there has at least one slice op. [:] been applied to the array, ought to be held in the '.status' element of the arrayobject struct. Or perhaps the number of slice ops done ought to be kept in that field ...) Hmm, that's enough for the moment I think (anybody still reading this ???). Hope this wasn't to obfuscated (my thoughts and my english, that is ...). Are their any design problems with my proposed array type ? Anything to consider, to make it fit better into the Python frame ? Is it impossible to do, what I'm trying to, because of language limitations or design decisions in the Python compiler/interpreter ? Any ideas ??? Thanks in advance, STefan -- Stefan Esser, Institute of Nuclear Physics, University of Cologne, Germany se@IKP.Uni-Koeln.DE [134.95.192.50] se@MI.Uni-Koeln.DE [134.95.208.16] Received: from hopscotch.ksr.com by charon.cwi.nl with SMTP id AA17735 (5.65b/3.8/CWI-Amsterdam); Wed, 27 Jan 1993 03:16:28 +0100 Received: from ksr.com (frankenstein.ksr.com) by hopscotch.ksr.com with SMTP id AA00718; Tue, 26 Jan 1993 21:12:57 -0500 Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA16200; Tue, 26 Jan 93 21:18:27 EST Received: by kaos.ksr.com (4.0/KSR-2.0) id AA16665; Tue, 26 Jan 93 21:18:26 EST Message-Id: <9301270218.AA16665@kaos.ksr.com> To: Jaap Vermeulen <jaap@sequent.com> Subject: Re: passing variable length arguments without unpacking them Cc: python-list@cwi.nl Date: Tue, 26 Jan 93 21:18:25 EST From: Tim Peters <tim@ksr.com> > I'm using python 0.9.8 and try to use the variable length arguments > ... > I cannot arbitrarily pass along a set of arguments without interpreting > them. For example (albeit articifial): > > count = 10 > def recurse(*args): > global count > count = count - 1 > if (count == 0): one, two, three = args > else: recurse(args) > > recurse(1, 2, 3) > > This will fail. ... Let me stick in a print so it's easier to see why it fails: count = 10 def recurse(*args): global count print 'Entering recurse, count =', count, 'args =', args count = count - 1 if (count == 0): one, two, three = args else: recurse(args) This yields: >>> recurse(1,2,3) Entering recurse, count = 10 args = (1, 2, 3) Entering recurse, count = 9 args = ((1, 2, 3),) Entering recurse, count = 8 args = (((1, 2, 3),),) Entering recurse, count = 7 args = ((((1, 2, 3),),),) Entering recurse, count = 6 args = (((((1, 2, 3),),),),) Entering recurse, count = 5 args = ((((((1, 2, 3),),),),),) Entering recurse, count = 4 args = (((((((1, 2, 3),),),),),),) Entering recurse, count = 3 args = ((((((((1, 2, 3),),),),),),),) Entering recurse, count = 2 args = (((((((((1, 2, 3),),),),),),),),) Entering recurse, count = 1 args = ((((((((((1, 2, 3),),),),),),),),),) ValueError: unpack tuple of wrong size Stack backtrace (innermost last): File "<stdin>", line 1 File "./temp.py", line 7 else: recurse(args) File "./temp.py", line 7 else: recurse(args) File "./temp.py", line 7 else: recurse(args) File "./temp.py", line 7 else: recurse(args) File "./temp.py", line 7 else: recurse(args) File "./temp.py", line 7 else: recurse(args) File "./temp.py", line 7 else: recurse(args) File "./temp.py", line 7 else: recurse(args) File "./temp.py", line 7 else: recurse(args) File "./temp.py", line 6 if (count == 0): one, two, three = args >>> I understand that this isn't what you want, but the rule does seem clear & consistent: a "*" formal argument sees a tuple comprising the actual arguments. The behavior of recurse is at least predictable given that. And at least I find it very natural <grin>. Your problem is that, in trying to pass the argument list on, you're actually passing a tuple instead of the original argument list. The built-in function "apply" goes the other direction, making a tuple act as if it were an argument list. This solves the problem nicely: count = 10 def rec2(*args): global count print 'Entering rec2, count =', count, 'args =', args count = count - 1 if (count == 0): one, two, three = args else: apply(rec2,args) # only line that's substantially different This yields: >>> rec2(1,2,3) Entering rec2, count = 10 args = (1, 2, 3) Entering rec2, count = 9 args = (1, 2, 3) Entering rec2, count = 8 args = (1, 2, 3) Entering rec2, count = 7 args = (1, 2, 3) Entering rec2, count = 6 args = (1, 2, 3) Entering rec2, count = 5 args = (1, 2, 3) Entering rec2, count = 4 args = (1, 2, 3) Entering rec2, count = 3 args = (1, 2, 3) Entering rec2, count = 2 args = (1, 2, 3) Entering rec2, count = 1 args = (1, 2, 3) >>> > In reality I'm using this in class initialization routines, where I try > to do something like: [a reasonable thing to want to do deleted] ... I confess I didn't try it, but I _believe_ the same technique will solve your subclass/subsubclass/etc problems. > ... > Any solutions to these problems? hoping-that-did-the-trick-for-you!-ly y'rs - tim Tim Peters tim@ksr.com not speaking for Kendall Square Research Corp Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA18230 (5.65b/3.8/CWI-Amsterdam); Wed, 27 Jan 1993 03:34:37 +0100 Received: from eng2.sequent.com by gateway.sequent.com (5.61/1.34) id AA03270; Tue, 26 Jan 93 18:35:21 -0800 Received: by eng2.sequent.com (5.65/1.34) id AA20963; Tue, 26 Jan 93 18:34:27 -0800 Message-Id: <9301270234.AA20963@eng2.sequent.com> To: Tim Peters <tim@ksr.com> Cc: python-list@cwi.nl Subject: Re: passing variable length arguments without unpacking them Priority: Normal Precedence: first-class Organization: Sequent Computer Systems, Inc. Service Technology - MailStop: RHE2-758 15450 S.W. Koll Parkway Beaverton, OR 97006 X-Phone: (503) 578-4404 X-Fax: (503) 578-7569 X-Uucp: ...!uunet!sequent!jaap X-Internet: jaap@sequent.com X-Face: C4Cnai$>Eja5I6Vq?(gdN#SXX#`-XgAnmUn&e54sx7@1>q@vkrd_XnH![P>w.:7IJJ;{Bts WJd)u&G!V}0OR?2o5cUgIY}.T{g]PMC=*~]3n_t)S-ZkC(WG}3:#hcA6Oazx:}yc&k,hsF7D},7x>l nyfRjO7$@]fHBN>aC9-M3pKfbYHiy!PWD{_bx~fo})b4tU.;Ao%x[upCI, In-Reply-To: Tim Peters's message of Tue, 26 Jan 1993 21:18:25 -0500. <9301270218.AA16665@kaos.ksr.com> Date: Tue, 26 Jan 1993 18:34:26 -0800 From: Jaap Vermeulen <jaap@sequent.com> | Your problem is that, in trying to pass the argument list on, you're | actually passing a tuple instead of the original argument list. The | built-in function "apply" goes the other direction, making a tuple act as | if it were an argument list. This solves the problem nicely: I knew I was overlooking something. Thanks for the solution. I remembered vaguely that I read something about it in the manuals, but wasn't willing to reread everything to find it. HINT FOR GUIDO: I did read the sections about functions in the reference manual and I don't think it referred to apply() whatsoever (it *did* talk about variable argument lists). I was thrown off by the non-intuitive fact that a tuple *will* get unpacked when assigned to formal arguments directly, i.e.: >>> def fun1(arg1, arg2): ... pass ... >>> fun1((1, 2)) >>> works like a champ. I guess this is for backwards compatibility. Thanks again, -Jaap- -- Jaap Vermeulen +--------------------------+ | Sequent Computer Systems | Internet : jaap@sequent.com | Beaverton, Oregon | Uucp : ...uunet!sequent!jaap +--------------------------+ Received: from hopscotch.ksr.com by charon.cwi.nl with SMTP id AA19008 (5.65b/3.8/CWI-Amsterdam); Wed, 27 Jan 1993 04:34:05 +0100 Received: from ksr.com (frankenstein.ksr.com) by hopscotch.ksr.com with SMTP id AA00835; Tue, 26 Jan 1993 22:30:50 -0500 Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA17298; Tue, 26 Jan 93 22:36:20 EST Received: by kaos.ksr.com (4.0/KSR-2.0) id AA17468; Tue, 26 Jan 93 22:36:19 EST Message-Id: <9301270336.AA17468@kaos.ksr.com> To: Jaap Vermeulen <jaap@sequent.com> Subject: Re: passing variable length arguments without unpacking them Cc: python-list@cwi.nl Date: Tue, 26 Jan 93 22:36:19 EST From: Tim Peters <tim@ksr.com> You're welcome, Jaap! I'm happy if it solved your problem. > ... > I was thrown off by the non-intuitive fact that a tuple *will* get > unpacked when assigned to formal arguments directly, i.e.: > > >>> def fun1(arg1, arg2): > ... pass > ... > >>> fun1((1, 2)) > >>> > > works like a champ. I guess this is for backwards compatibility. Speaking of remembering you've seen something but can't quite recall where, I just found this (again) in python-NEWS-0.9.8: > (There's a third compatibility hack, which is the reverse of (a): if a > function is defined with two or more arguments, and called with a > single argument that is a tuple with just as many arguments, the items > of this tuple will be used as the arguments. Although this can (and > should!) be done using the built-in function apply() instead, it isn't > withdrawn yet.) So, as usual, Guido addressed all our questions long before we thought of them <grin>. Maybe this is cause for hope: Python has tried a few sets of rules for dealing with tuples vs arglists, and for getting the effect of variable argument lists, & I believe 0.9.8's rules are the first set I feel I can predict in all cases without "looking it up" once a week (of course I'm talking about the documented rules -- the reference manual doesn't claim you can get away with the example above). so-it-feels-like-progress-to-me-ly y'rs - tim Tim Peters tim@ksr.com not speaking for Kendall Square Research Corp Received: from relay2.UU.NET by charon.cwi.nl with SMTP id AA20591 (5.65b/3.8/CWI-Amsterdam); Tue, 2 Feb 1993 16:26:45 +0100 Received: from uunet.uu.net (via LOCALHOST.UU.NET) by relay2.UU.NET with SMTP (5.61/UUNET-internet-primary) id AA16029; Tue, 2 Feb 93 10:26:46 -0500 Received: from astro.UUCP by uunet.uu.net with UUCP/RMAIL (queueing-rmail) id 102538.29485; Tue, 2 Feb 1993 10:25:38 EST Received: by astro.sunrise.com (/\==/\ Smail3.1.22.1 #22.3) id <m0nJOp7-0003zvC@astro.sunrise.com>; Tue, 2 Feb 93 09:42 EST Message-Id: <m0nJOp7-0003zvC@astro.sunrise.com> From: drew@sunrise.com (Drew Jenkins) Subject: PC Window Bindings? To: python-list@cwi.nl Date: Tue, 2 Feb 93 9:42:00 EST X-Mailer: ELM [version 2.3 PL11] Just curious, has anyone created any kind of python bindings to the DOS Window environment? Drew Jenkins "Attitude is Everything" drew@sunrise.com -- Bingen Bart Received: from hp.com by charon.cwi.nl with SMTP id AA22361 (5.65b/3.8/CWI-Amsterdam); Tue, 2 Feb 1993 17:22:03 +0100 Received: from hpavuu.avo.hp.com by hp.com with SMTP (16.8/15.5+IOS 3.13) id AA19886; Tue, 2 Feb 93 08:21:56 -0800 Received: by hpavun.lf.hp.com (16.8/15.5+IOS 3.22) id AA01060; Tue, 2 Feb 93 11:22:43 -0500 Date: Tue, 2 Feb 93 11:22:43 -0500 From: John DeGood <degood@lf.hp.com> Message-Id: <9302021622.AA01060@hpavun.lf.hp.com> To: drew@sunrise.com Subject: Re: PC Window Bindings? Cc: python-list@cwi.nl > Just curious, has anyone created any kind of python bindings > to the DOS Window environment? I was afraid that someone would ask that question someday. :-) I began a STDWIN port to Microsoft Windows last year. Guido suggested that I use Python to import and test the STDWIN functions, so I also ported Python to run in a text window under Windows. It turned out to definitely be worth the several evenings effort it took to get Python running under Windows as it made my STDWIN test/debug/fix cycle so much easier. This is strictly a "g-job" project that I work on at home in my "spare" time. I have fully implemented many of the STDWIN functions but there is still much work remaining. I don't expect to complete the port before mid-year: the arrival of our second child in November slowed my progress! I'll post an announcement to this mailing list when I complete the port. John DeGood degood@lf.hp.com Hewlett-Packard Little Falls Site (Wilmington, Delaware) Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA13934 (5.65b/3.8/CWI-Amsterdam); Sun, 7 Feb 1993 17:59:41 +0100 Received: by voorn.cwi.nl with SMTP id AA29838 (5.65b/3.8/CWI-Amsterdam); Sun, 7 Feb 1993 17:59:41 +0100 Message-Id: <9302071659.AA29838=guido@voorn.cwi.nl> To: python-list@cwi.nl Subject: An ARRAY type for Python From: Guido.van.Rossum@cwi.nl X-Organization: CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Sun, 07 Feb 1993 17:59:40 +0100 Sender: Guido.van.Rossum@cwi.nl About two weeks ago Stefan Esser asked about an array type for Python. Actually his question consisted of two parts: (1) he wanted an array of objects represented as machine words -- an extension of the string type, really; and (2) he wanted to extend Python with a notion of multidimensional arrays. I've been rather busy lately so I haven't found the time to answer either question, so far. (Sorry Stefan!) But I did get an idea that would address at least the first question. Let me start by explaining some background. Python's notion of sequences has always been intended to allow extension with new kinds of sequences. The minimal set of properties of a sequence object a is that it has a length, len(a), and that if 0 <= i < len(a): a[i] is defined (and for all other i, a[i] is not defined). The semantics of slicing, concatenation and repetition (a[i:j], a+b and a*k) are also fixed. An extension to mutable sequences allows assignment to items, to slices, and the list operations append and insert. (The operations remove, index, count, reverse and sort are perhaps better seen as specific to the list type.) The existing sequence types in Python are list, tuple and string. But we can easily extend this with arrays of machine integers, say. Such an array would behave like a list in most circumstances, but it would restrict the values contained in the list to machine integers, and therefore a more compact representation can be used. I have written a module that creates such arrays, with various types of of values (characters, integers of 3 sizes, float and double), and placed it on ftp.cwi.nl:/pub/python in file arraymodule.c. If you have dynamic loading in your Python, you can just compile it and import it (the file arraymodule.libs should contain the name of the C library, e.g. /lib/libc.a; on SGI's -lc_s is better). Otherwise you can add it to your Python interpreter by using the Addmodule.sh script and rebuilding Python. Here's a short description of my array module. ======================================================================== The module array defines one function. array(typecode, initializer) Return a new array whose items are restricted by the typecode, and initialized from the (optional) initializer value. The typecode is a character which defines the item type (users of the getattr() C function in the Python interpreter will recognize this): 'c' - charcter 'b' - 1-byte signed integer 'h' - 2-byte signed integer 'l' - 4-byte signed integer 'f' - float 'd' - double If an initializer is present, it must be a list or a string. The list or string is passed to the new array's fromlist() or fromstring() method (see below) to add initial items to the array. Array objects are mutable sequence types and support the following data items and methods. typecode The typecode character used to create the array itemsize The length in bytes of one array item in the internal representation append(x) Append a new item with value x to the end of the array. insert(i, x) Insert a new item with value x in the array before position i. read(f, n) Read n items (as machine values) from the file object f and append them to the end of the array. If less than n items are available, EOFError is raised, but the items that were available are still inserted into the array. write(f) Write all items (as machine values) to the file object f. fromstring(s) Appends items from the string, interpreting the string as an array of machine values (i.e. as if it had been read from a file using the read() method). tostring() Convert the array to an array of machine values and return the string representation (the same sequence of bytes that would be written to a file by the write() method.) fromlist(l) Appends items from the list. This is equivalent to for x in l: a.append(x) except that if there is a type error, the array is unchanged. tolist() Convert the array to an ordinary list with the same items. When an array object is printed or converted to a string, it is represented as array(<typecode>, <initializer>). The initializer is omitted if the array is empty, otherwise it is a string if the typecode is 'c', otherwise it is a list of numbers. The string is guaranteed to be able to be converted back to an array with the same type and value using reverse quotes (``). Examples: array('l') array('c', 'hello world') array('l', [1, 2, 3, 4, 5]) array('d', [1.0, 2.0, 3.14]) ======================================================================== Adding multidimensional arrays to Python is harder, since the interpreter currently doesn't know about this concept. I have some ideas that don't require extending the Python syntax, which basically boil down to separating the actual array data from a definition of how the rows and columns are laid out (e.g. one could transpose an array without copying the data). I'll work on this a little more and maybe it'll see the light of day. In the mean time, please try out my array module and report any bugs or functionality you would like to see added to me -- it may become a standard module in the next release. Cheers, --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Wed, 10 Feb 1993 10:18:21 +0100 Replied: "Lance Ellinghouse <lance@markv.com> python-list" Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA11988 (5.65b/3.8/CWI-Amsterdam); Wed, 10 Feb 1993 03:45:21 +0100 From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: python-list@cwi.nl Subject: setting <stdin> to RAW mode??? Date: Tue, 9 Feb 93 18:45:00 PST Message-Id: <9302091845.aa22168@hermix.markv.com> Does anyone know of a quick easy way to set sys.stdin to be in RAW mode? (non-buffered, etc) I would like to be able to call sys.stdin.read(1) and have it return when it really reads 1 char and only 1 char WITHOUT echo... Lance Ellinghouse lance@markv.com To: Lance Ellinghouse <lance@markv.com> cc: python-list Subject: Re: setting <stdin> to RAW mode??? In-reply-to: Your message of "Tue, 09 Feb 1993 18:45:00 MET." <9302091845.aa22168@hermix.markv.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Wed, 10 Feb 1993 10:18:21 +0100 Sender: guido >Does anyone know of a quick easy way to set sys.stdin to be in >RAW mode? (non-buffered, etc) >I would like to be able to call sys.stdin.read(1) and have it >return when it really reads 1 char and only 1 char WITHOUT echo... Well, you could always try something along the lines of import os sts = os.system('stty raw') if sts: print '"stty raw" failed, exit status', sts There's also the optional ioctl module, but I wouldn't call it quick and easy, and I have no examples at hand. It is also (even) less portable to use... Note that you should probably use "try...finally" to make sure that the tty status is reset to normal when the program exits, even if it crashes, otherwise your shell finds itself in raw mode. If you are using System V or a derivative, or even SunOS, you can use code like this: import os saved_tty_state = os.popen('stty -g', 'r').read() try: sts = os.system('stty raw') ... ...code using raw mode goes here ... finally: sts = os.system('stty ' + saved_tty_state) The 'stty -g' command returns a string that compactly encodes all tty settings; passing this string as an argument back to stty restores these tty settings exactly. The "finally" clause gets executed even if your code hits an exception, but it does not prevent a stack trace (unlike "except", which lets your program continue normally). --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA06744 (5.65b/3.8/CWI-Amsterdam); Fri, 12 Feb 1993 03:46:18 +0100 Received: by hermix.markv.com id aa16252; 11 Feb 93 18:45 PST From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: junknews.py@markv.com, python-list@cwi.nl Subject: Python program to create groups for Cnews Date: Thu, 11 Feb 93 18:35:17 PST Message-Id: <9302111835.aa13609@hermix.markv.com> I was tired of creating groups for Cnews by hand.. I whipped up a little program to do it for me.. All you have to do is change to vars at the beginning and away it goes.. if you find any problems or want to make it better, let me know.. Thanks! Lance Ellinghouse lance@markv.com --- Cut Here: #! /usr2/local/bin/python # This file takes and scans for files in the "junk" directory # of Cnews. It then creates groups based on the Newsgroups: line # in these files. It then exits. import sys, os, string junkdir='/usr/spool/cnews/junk/' bindir='/usr2/lib/newsbin/maint/' def get_groups(file_name): try: fd=open(file_name,'r') except: print 'cannot open ' + file_name return [] while 1: try: line=fd.readline() except EOFError: return [] line=string.strip(line) if line[:11] == 'Newsgroups:': groups = string.splitfields(line[12:],',') return groups if len(line) == 0: return [] def make_groups(groups): for group in groups: os.system(bindir + 'addgroup ' + group + ' y') def main(): os.chdir(junkdir) for file_name in os.listdir('.'): if file_name not in ['.','..']: print 'processing ' + file_name rtn = make_groups(get_groups(file_name)) main() Replied: Fri, 12 Feb 1993 12:46:40 +0100 Replied: "Jack Jansen <Jack.Jansen@cwi.nl> python-list@cwi.nl" Received: from schelvis.cwi.nl by charon.cwi.nl with SMTP id AA16548 (5.65b/3.8/CWI-Amsterdam); Fri, 12 Feb 1993 10:40:19 +0100 Received: by schelvis.cwi.nl with SMTP id AA06273 (5.65b/3.8/CWI-Amsterdam); Fri, 12 Feb 1993 10:40:19 +0100 Message-Id: <9302120940.AA06273=jack@schelvis.cwi.nl> To: python-list@cwi.nl Subject: Re: Python program to create groups for Cnews In-Reply-To: Message by Lance Ellinghouse <lance@markv.com> , Thu, 11 Feb 93 18:35:17 PST , <9302111835.aa13609@hermix.markv.com> Organisation: Multi-media group, CWI, Kruislaan 413, Amsterdam Phone: +31 20 5924098(work), +31 20 5924199 (fax), +31 20 6160335(home) X-Last-Band-Seen: de Abbas (Paradiso, 9-2) X-Mini-Review: Brilliant! Abba ripped to shreds in a great way! Date: Fri, 12 Feb 1993 10:40:18 +0100 From: Jack Jansen <Jack.Jansen@cwi.nl> That message remindss me: does anyone happen to have an rfc822 parser in python? -- Jack Jansen | If I can't dance I don't want to be part of Jack.Jansen@cwi.nl | your revolution -- Emma Goldman uunet!cwi.nl!jack G=Jack;S=Jansen;O=cwi;PRMD=surf;ADMD=400net;C=nl Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA19421 (5.65b/3.8/CWI-Amsterdam); Fri, 12 Feb 1993 12:46:40 +0100 Received: by voorn.cwi.nl with SMTP id AA04725 (5.65b/3.8/CWI-Amsterdam); Fri, 12 Feb 1993 12:46:40 +0100 Message-Id: <9302121146.AA04725=guido@voorn.cwi.nl> To: Jack Jansen <Jack.Jansen@cwi.nl> Cc: python-list@cwi.nl Subject: Re: Python program to create groups for Cnews In-Reply-To: Your message of "Fri, 12 Feb 1993 10:40:18 MET." <9302120940.AA06273=jack@schelvis.cwi.nl> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Fri, 12 Feb 1993 12:46:39 +0100 Sender: Guido.van.Rossum@cwi.nl >That message remindss me: does anyone happen to have an rfc822 parser >in python? Try looking at lib/rfc822.py in the 0.9.8 release (or in my home directory :-). It's not complete but does do essentials like parsing continuation lines, and gives you a list containing the broken-down header. --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from mcsun.EU.net by charon.cwi.nl with SMTP id AA20086 (5.65b/3.8/CWI-Amsterdam); Sat, 13 Feb 1993 03:54:27 +0100 Received: by mcsun.EU.net via EUnet id AA23251 (5.65b/CWI-2.206); Sat, 13 Feb 1993 03:54:26 +0100 Received: from ghost.uunet.ca (via uunet.ca) by relay1.UU.NET with SMTP (5.61/UUNET-internet-primary) id AA18653; Fri, 12 Feb 93 21:52:41 -0500 Received: from snitor by mail.uunet.ca with UUCP id <11310>; Fri, 12 Feb 1993 16:52:44 -0500 Received: from radium.sni.ca by snitor.sni.ca (5.61/smail2.5/07-11-92) id AA07346; Fri, 12 Feb 93 13:26:39 -0500 Received: by radium.sni.CA (5.61/smail2.5/02-09-92) id AA15987; Fri, 12 Feb 93 13:26:29 -0500 Date: Fri, 12 Feb 1993 13:26:29 -0500 From: tracy@snitor.sni.ca (Tracy Tims) Message-Id: <9302121826.AA15987@radium.sni.CA> To: python-list@cwi.nl Subject: mail and news header parsers I also have a python function that can parse rfc822 headers, but it is designed for parsing general rfc822 forms--news articles, mailboxes, rfc822 messages, and various distortions of these. It is designed to be able to recognise the individual messages in a multi-message file, with a wide variety of header types. I'm using it as the message-parsing backbone for a message-and-file indexing system that I'm (slowly) writing. Tracy Tims Received: from mcsun.EU.net by charon.cwi.nl with SMTP id AA17952 (5.65b/3.8/CWI-Amsterdam); Sat, 20 Feb 1993 00:49:43 +0100 Received: by mcsun.EU.net via EUnet id AA06945 (5.65b/CWI-2.207); Sat, 20 Feb 1993 00:49:40 +0100 Received: from ghost.uunet.ca (via uunet.ca) by relay1.UU.NET with SMTP (5.61/UUNET-internet-primary) id AA09498; Fri, 19 Feb 93 18:48:21 -0500 Received: from snitor by mail.uunet.ca with UUCP id <9761(2)>; Fri, 19 Feb 1993 18:47:55 -0500 Received: from radium.sni.ca by snitor.sni.ca (5.61/smail2.5/07-11-92) id AA10525; Fri, 19 Feb 93 16:59:31 -0500 Received: by radium.sni.CA (5.61/smail2.5/02-09-92) id AA00310; Fri, 19 Feb 93 16:59:27 -0500 Date: Fri, 19 Feb 1993 16:59:27 -0500 From: tracy@snitor.sni.ca (Tracy Tims) Message-Id: <9302192159.AA00310@radium.sni.CA> To: Guido.van.Rossum@cwi.nl Cc: python-list@cwi.nl Subject: Sugar for regular expression groupings. I find myself using regex.compile() frequently for parsing lines from various data-files. I write a regular expression that contains a number of \( and \) groupings, and then I use slice notation to fetch the tokens I want from the line. Here's an example: format = regex.compile( a_pattern) if format.match( data) != -1: old_ver = data[format.regs[1][0]:format.regs[1][1]] new_ver = data[format.regs[2][0]:format.regs[2][1]] user = data[format.regs[3][0]:format.regs[3][1]] date = data[format.regs[4][0]:format.regs[4][1]] time = data[format.regs[5][0]:format.regs[5][1]] host = data[format.regs[6][0]:format.regs[6][1]] dir = data[format.regs[7][0]:format.regs[7][1]] I use the slice notation/regex register code over and over again, in many programs. This is so common that perhaps there should be a clearer way to do this. (I've seen the idiom in fpformat.py, and it doesn't make me completely happy.) What if a compiled regular expression object had an attribute which was a reference to the last string on which it sucessfully matched (I think this is a good idea anyway--I have always been uncomfortable with the fact that a regular expression object only contains half of the information needed to extract groups), and if it had a simple method for returning groups out of the matched string? I could reduce the example above to the following: if format.match( data) != -1: old_ver, new_ver, user, date, time, host, dir \ = format.groups(1,2,3,4,5,6,7) Code using the groups() method is easier to modify and maintain because it doesn't have the internal interdependencies that the first example has (and the fpformat.py idiom also has). Tracy Tims Replied: Sun, 21 Feb 1993 18:36:50 +0100 Replied: "python-list " Received: from hopscotch.ksr.com by charon.cwi.nl with SMTP id AA26445 (5.65b/3.8/CWI-Amsterdam); Sat, 20 Feb 1993 03:04:20 +0100 Received: from ksr.com (frankenstein.ksr.com) by hopscotch.ksr.com with SMTP id AA01551; Fri, 19 Feb 1993 21:00:20 -0500 Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA27070; Fri, 19 Feb 93 20:58:13 EST Received: by kaos.ksr.com (4.1/KSR-2.0) id AA27540; Fri, 19 Feb 93 20:58:09 EST Message-Id: <9302200158.AA27540@kaos.ksr.com> To: tracy@snitor.sni.ca Subject: Re: Sugar for regular expression groupings. Cc: python-list@cwi.nl Date: Fri, 19 Feb 93 20:58:08 EST From: Tim Peters <tim@ksr.com> > [Tracy Tims writes ...] > I find myself using regex.compile() frequently for parsing lines from > various data-files. ... > [notes that breaking out fields is clumsy & error-prone, a la ...] > > format = regex.compile( a_pattern) > > if format.match( data) != -1: > old_ver = data[format.regs[1][0]:format.regs[1][1]] > new_ver = data[format.regs[2][0]:format.regs[2][1]] > user = data[format.regs[3][0]:format.regs[3][1]] > date = data[format.regs[4][0]:format.regs[4][1]] > time = data[format.regs[5][0]:format.regs[5][1]] > host = data[format.regs[6][0]:format.regs[6][1]] > dir = data[format.regs[7][0]:format.regs[7][1]] > ... > [but with some changes ...] > I could reduce the example above to the following: > > if format.match( data) != -1: > old_ver, new_ver, user, date, time, host, dir \ > = format.groups(1,2,3,4,5,6,7) > > Code using the groups() method is easier to modify and maintain > because it doesn't have the internal interdependencies that the first > example has (and the fpformat.py idiom also has). I'll whine louder <grin>: even given those changes, you still have a maintenance nightmare because of the ubiquitous reliance on meaningless little integers to denote the fields. If the format of the data file changes, or even if it doesn't but you decide you need to extract some more info "in the middle" (a common desire as applications grow fancier), the relative indices of the parentheses may change. Then you've got to track down all the references in the code & change 'em. Attached is module regex2.py, a homegrown way to worm around those problems. I haven't gotten around to documenting it, but an example should make it clear enough to understand what the code is doing. I'll use the regexp from fpformat.py for familiarity's sake: >>> import regex2 >>> fpre = '^\([-+]?\)0*\([0-9]*\)\(\(\.[0-9]*\)?\)\(\([eE][-+]?[0-9]+\)?\)$' >>> decoder = regex2.compile( fpre, 'all','sign','int','frac','junk','exp') >>> decoder.match('-2.3e45') 7 >>> decoder.matches_by_index(0,2,2,6) ('-2.3e45', '2', '2', 'e45') >>> decoder.matches_by_name('sign','int','frac','exp') ('-', '2', '.3', 'e45') >>> decoder.match('abc') -1 >>> decoder.matches_by_name('int') regex2: last match failed Stack backtrace (innermost last): File "<stdin>", line 1 File "./regex2.py", line 41 raise error >>> So your "groups" method is named "matches_by_index" here, & there's also a "matches_by_name" method that confines the dependence on little integers to a single line (the fields are (optionally) named at the time the regexp is compiled). It also arranges to gripe if a "matches_by_..." method is invoked when the preceding search or match attempt failed; that may or may not be a feature (eye of the beholder; obviously, I like it that way). Give it a try & see how you like it! This kind of thing is very easy to do in Python, so play around & see if you can come up with something you like better. the-trick-to-motivating-guido-to-change-python-is-to-come-up-with- something-*he*-likes-better<grin>-ly y'rs - tim Tim Peters tim@ksr.com not speaking for Kendall Square Research Corp Module regex2.py: import regex error = 'regex2: last match failed' def compile( pattern, *field_names ): answer = _Regex2() answer.pattern = pattern # currently unused answer.compiled_re = regex.compile( pattern ) answer.matched_string = None answer.name2index = {} i = 0 for name in field_names: answer.name2index[name] = i i = i + 1 return answer class _Regex2: def match( self, string ): a = self.compiled_re.match( string ) if a >= 0: self.matched_string = string else: self.matched_string = None return a def search( self, string ): a = self.compiled_re.search( string ) if a >= 0: self.matched_string = string else: self.matched_string = None return a def matches_by_index( self, *indices ): if self.matched_string is None: raise error answer = () for n in indices: start, end = self.compiled_re.regs[n] answer = answer + (self.matched_string[start:end],) return answer def matches_by_name( self, *field_names ): if self.matched_string is None: raise error answer = () for name in field_names: i = self.name2index[name] start, end = self.compiled_re.regs[i] answer = answer + (self.matched_string[start:end],) return answer END OF MSG To: python-list Subject: Re: Sugar for regular expression groupings. In-reply-to: Your message of "Fri, 19 Feb 1993 20:58:08 MET." <9302200158.AA27540@kaos.ksr.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Sun, 21 Feb 1993 18:36:50 +0100 Sender: guido Thanks for your ideas, Tracy and Tim! I like the idea of saving a reference to the last matched string and providing a varargs function to access substrings. I'll try to put this (as C code) in the next release. I don't think the interface to access substrings by name instead of by number buys you much (except an advantage over Perl :-). You can always define constants to name the substrings near the place where you write down the pattern. Off to coding, --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from hopscotch.ksr.com by charon.cwi.nl with SMTP id AA23418 (5.65b/3.8/CWI-Amsterdam); Mon, 22 Feb 1993 03:47:35 +0100 Received: from ksr.com (frankenstein.ksr.com) by hopscotch.ksr.com with SMTP id AA00698; Sun, 21 Feb 1993 21:43:24 -0500 Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA04898; Sun, 21 Feb 93 21:41:25 EST Received: by kaos.ksr.com (4.1/KSR-2.0) id AA07381; Sun, 21 Feb 93 21:41:21 EST Message-Id: <9302220241.AA07381@kaos.ksr.com> To: Guido.van.Rossum@cwi.nl Subject: Re: Sugar for regular expression groupings. Cc: python-list@cwi.nl Date: Sun, 21 Feb 93 21:41:19 EST From: Tim Peters <tim@ksr.com> Status: RO > [guido] > ... > I like the idea of saving a reference to the last matched string and > providing a varargs function to access substrings. I'll try to put > this (as C code) in the next release. Cool! > I don't think the interface to access substrings by name instead of by > number buys you much Not initially, no ... it's a year later when the format changes that the pain begins <smile>. Still, I wouldn't _recommend_ people generally use a name interface either, cuz no matter how it's done it's gonna be pretty slow. For that reason, I don't use a name interface myself for regexp- crunching on large volumes of data. > (except an advantage over Perl :-). Having a regexp _object_ is an advantage over Perl already; the Perl folks ask for "something like that" regularly. But getting the effect of named fields is already easy in Perl. E.g., for the fpformat.py example: >>> fpre = '^\([-+]?\)0*\([0-9]*\)\(\(\.[0-9]*\)?\)\(\([eE][-+]?[0-9]+\)?\)$' >>> decoder = regex2.compile( fpre, 'all','sign','int','frac','junk','exp') >>> decoder.match('-2.3e45') 7 >>> decoder.matches_by_name('sign','int','frac','exp') ('-', '2', '.3', 'e45') In idiomatic Perl that looks like: $fpre = '^([-+]?)0*(\d*)((\.\d*)?)((e[-+]?\d+)?)$'; ($sign,$int,$frac,$junk,$exp) = '-2.3e45' =~ /$fpre/io; print "$sign $int $frac $exp\n"; which prints "- 2 .3 e45". A pretty close equivalent in Python would be if a compiled regexp's search method returned a tuple with a number of elements equal to the number of meta-parentheses in the regexp: >>> sign,int,frac,junk,exp = decoder.hypothetical_search('-2.3e45') where `sign' etc are bound to None if the search fails. This way has attractions too. Lots of ways to skin this cat <smile>! I hope someone who does a lot of regexp crunching (I really don't) tries out several approaches & says what they like best. > You can always define constants to name the substrings near the place > where you write down the pattern. That's fine by me, although there's a little danger from unintended namespace collisions. A suggestion for people who intend to do that: Instead of defining the "constants" like this: ALL = 0 SIGN = 1 INT = 2 FRAC = 3 JUNK = 4 EXP = 5 Do it like this: [ALL, SIGN, INT, FRAC, JUNK, EXP] = range(6) You'll be glad you did when things change ... agreeably y'rs - tim Tim Peters tim@ksr.com not speaking for Kendall Square Research Corp Received: from mcsun.EU.net by charon.cwi.nl with SMTP id AA08464 (5.65b/3.8/CWI-Amsterdam); Mon, 22 Feb 1993 16:55:01 +0100 Received: by mcsun.EU.net via EUnet id AA00746 (5.65b/CWI-2.207); Mon, 22 Feb 1993 16:55:00 +0100 Received: from ghost.uunet.ca (via uunet.ca) by relay1.UU.NET with SMTP (5.61/UUNET-internet-primary) id AA07069; Mon, 22 Feb 93 10:51:02 -0500 Received: from snitor by mail.uunet.ca with UUCP id <9670(1)>; Mon, 22 Feb 1993 10:50:50 -0500 Received: from radium.sni.ca by snitor.sni.ca (5.61/smail2.5/07-11-92) id AA01368; Mon, 22 Feb 93 10:07:24 -0500 Received: by radium.sni.CA (5.61/smail2.5/02-09-92) id AA03386; Mon, 22 Feb 93 10:07:13 -0500 Date: Mon, 22 Feb 1993 10:07:13 -0500 From: tracy@snitor.sni.ca (Tracy Tims) Message-Id: <9302221507.AA03386@radium.sni.CA> To: tim@ksr.com Cc: python-list@cwi.nl In-Reply-To: Tim Peters's message of Fri, 19 Feb 1993 20:58:08 -0500 <9302200158.AA27540@kaos.ksr.com> Subject: Sugar for regular expression groupings. I ended up not writing my own regex class with symbolic group names for two reasons: if the feature is supplied in the standard python module it will be faster, and it will be more portable (or distributable). I also figured that Guido would be more likely to add a simpler solution, because it will be less work for most of the benefits. I can live with integer group names. I'll either symbolically name them, use them as is, or store complete argument lists for groups() along with my regular expressions. If necessary, symbolic group names can be added later without obsoleting 'regs' or the additions I propose. Improvement 1: Add an optional dictionary attribute to regex objects. Ex: regex.groupnames Add varargs to the compile() method that will automatically initially define the optional dictionary. Ex: regex.compile( re, 'group_1_name', 'group_2_name') Modify groups() so that if a string is given as a group-selector argument it is used to index the dictionary to obtain the group number. Ex: decode.groups( 1, 'group_2_name') This ends up looking like your solution, but the relationship between 'regs', groups(), and 'groupnames' is explicit. This is useful because it increases the number of "fruitful interactions". Improvement 2: Add syntax to regular expressions so that groups can be named in place, yielding the group dictionary. (This is a *big* advantage over perl.) For example: re = '[^0-9]*\(<number>[0-9]+\)[ \t]+\(<label>[A-Za-z_-.]+\)' decode = regex.compile( re) n, l = decode.groups( 'number', 'label') I like this idea, because then I can build complicated regular expressions in substrings, and then catenate them together into the final regular expression before compiling. It also completely eliminates group-counting, and it provides a visual indication of which groups are just for grouping, and which are for substring extraction. But what python really needs are LALR(1) parser objects, don't you think? Tracy Tims Replied: Tue, 23 Feb 1993 02:03:23 +0100 Replied: "Jaap Vermeulen <jaap@sequent.com> python-list" Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA11086 (5.65b/3.8/CWI-Amsterdam); Mon, 22 Feb 1993 18:50:16 +0100 Received: from eng2.sequent.com by gateway.sequent.com (5.61/1.34) id AA09230; Mon, 22 Feb 93 09:50:21 -0800 Received: by eng2.sequent.com (5.65/1.34) id AA01658; Mon, 22 Feb 93 09:50:00 -0800 Message-Id: <9302221750.AA01658@eng2.sequent.com> To: tracy@snitor.sni.ca (Tracy Tims) Cc: tim@ksr.com, python-list@cwi.nl Subject: Re: Sugar for regular expression groupings. Priority: Normal Precedence: first-class Organization: Sequent Computer Systems, Inc. Service Technology - MailStop: WIL2-610 15450 S.W. Koll Parkway Beaverton, OR 97006 X-Phone: (503) 578-4404 X-Fax: (503) 578-4540 X-Uucp: ...!uunet!sequent!jaap X-Internet: jaap@sequent.com X-Face: C4Cnai$>Eja5I6Vq?(gdN#SXX#`-XgAnmUn&e54sx7@1>q@vkrd_XnH![P>w.:7IJJ;{Bts WJd)u&G!V}0OR?2o5cUgIY}.T{g]PMC=*~]3n_t)S-ZkC(WG}3:#hcA6Oazx:}yc&k,hsF7D},7x>l nyfRjO7$@]fHBN>aC9-M3pKfbYHiy!PWD{_bx~fo})b4tU.;Ao%x[upCI, In-Reply-To: Tracy Tims's message of Mon, 22 Feb 1993 10:07:13 -0500. <9302221507.AA03386@radium.sni.CA> Date: Mon, 22 Feb 1993 09:49:59 -0800 From: Jaap Vermeulen <jaap@sequent.com> | Improvement 2: | Add syntax to regular expressions so that groups can be named | in place, yielding the group dictionary. (This is a *big* | advantage over perl.) I stronly second this improvement. How often do I just guess which subexpression yields what result? Often, since I always have trouble counting nested subexpressions (and I'm sure I'm not the only one). | But what python really needs are LALR(1) parser objects, don't you | think? Yes, that would solve a lot of other problems I encountered while parsing *long* strings. $0.02 -Jaap- -- Jaap Vermeulen +--------------------------+ | Sequent Computer Systems | Internet : jaap@sequent.com | Beaverton, Oregon | Uucp : ...uunet!sequent!jaap +--------------------------+ To: Jaap Vermeulen <jaap@sequent.com> cc: python-list Subject: Re: Sugar for regular expression groupings. In-reply-to: Your message of "Mon, 22 Feb 1993 09:49:59 MET." <9302221750.AA01658@eng2.sequent.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Tue, 23 Feb 1993 02:03:23 +0100 Sender: guido > >| Improvement 2: >| Add syntax to regular expressions so that groups can be named >| in place, yielding the group dictionary. (This is a *big* >| advantage over perl.) > >I stronly second this improvement. How often do I just guess which >subexpression yields what result? Often, since I always have trouble >counting nested subexpressions (and I'm sure I'm not the only one). I'm afraid the trouble with this one is that the syntax of Python regular expressions is defined by the GNU Emacs regular expression package. I am using a Finnish reimplementation that is free of the GNU copyleft, but which follows the GNU syntax and interface quite precisely so it is possible to plug in the GNU Emacs code instead (which was slightly faster and a lot smaller if I remember it well). I can't say I understand this code and I would like not to modify it. So what can I do? Is it really that hard to count occurrences of \(? >| But what python really needs are LALR(1) parser objects, don't you >| think? > >Yes, that would solve a lot of other problems I encountered while >parsing *long* strings. That's an interesting thought. Unfortunately the only LALR(1) parser generators I know of are Yacc and Bison, and neither appears to be easily modified to generate its tables in a form different that C data structures (anyone here to contradict this statement?). Would you folks settle for a recursive descent parser generator (like the one used to build the Python parser)? That one I know how to hack... 'Night, --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA04715 (5.65b/3.8/CWI-Amsterdam); Tue, 23 Feb 1993 02:03:24 +0100 Received: by voorn.cwi.nl with SMTP id AA27447 (5.65b/3.8/CWI-Amsterdam); Tue, 23 Feb 1993 02:03:23 +0100 Message-Id: <9302230103.AA27447=guido@voorn.cwi.nl> To: Jaap Vermeulen <jaap@sequent.com> Cc: python-list@cwi.nl Subject: Re: Sugar for regular expression groupings. In-Reply-To: Your message of "Mon, 22 Feb 1993 09:49:59 MET." <9302221750.AA01658@eng2.sequent.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Tue, 23 Feb 1993 02:03:23 +0100 Sender: Guido.van.Rossum@cwi.nl > >| Improvement 2: >| Add syntax to regular expressions so that groups can be named >| in place, yielding the group dictionary. (This is a *big* >| advantage over perl.) > >I stronly second this improvement. How often do I just guess which >subexpression yields what result? Often, since I always have trouble >counting nested subexpressions (and I'm sure I'm not the only one). I'm afraid the trouble with this one is that the syntax of Python regular expressions is defined by the GNU Emacs regular expression package. I am using a Finnish reimplementation that is free of the GNU copyleft, but which follows the GNU syntax and interface quite precisely so it is possible to plug in the GNU Emacs code instead (which was slightly faster and a lot smaller if I remember it well). I can't say I understand this code and I would like not to modify it. So what can I do? Is it really that hard to count occurrences of \(? >| But what python really needs are LALR(1) parser objects, don't you >| think? > >Yes, that would solve a lot of other problems I encountered while >parsing *long* strings. That's an interesting thought. Unfortunately the only LALR(1) parser generators I know of are Yacc and Bison, and neither appears to be easily modified to generate its tables in a form different that C data structures (anyone here to contradict this statement?). Would you folks settle for a recursive descent parser generator (like the one used to build the Python parser)? That one I know how to hack... 'Night, --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from hopscotch.ksr.com by charon.cwi.nl with SMTP id AA11635 (5.65b/3.8/CWI-Amsterdam); Tue, 23 Feb 1993 07:03:25 +0100 Received: from ksr.com (frankenstein.ksr.com) by hopscotch.ksr.com with SMTP id AA21210; Tue, 23 Feb 1993 00:59:55 -0500 Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA20154; Tue, 23 Feb 93 01:02:53 EST Received: by kaos.ksr.com (4.1/KSR-2.0) id AA00153; Tue, 23 Feb 93 01:02:52 EST Message-Id: <9302230602.AA00153@kaos.ksr.com> To: tracy@snitor.sni.ca, jaap@sequent.com, Guido.van.Rossum@cwi.nl Subject: Re: Sugar for regular expression groupings. Cc: python-list@cwi.nl Date: Tue, 23 Feb 93 01:02:51 EST From: Tim Peters <tim@ksr.com> > [tracy] > I ended up not writing my own regex class with symbolic group names for > two reasons: if the feature is supplied in the standard python module > it will be faster, and it will be more portable (or distributable). Agree "faster" is likely, but don't understand the portable/distributable point: a module coded _in_ standard Python is quite portable! The advantage to doing it that way is it gives people a chance to experiment with the interface, before freezing it into the standard distribution. > ... I can live with integer group names. Me too! > [various improvements: groupnames attribute; optional varargs to > 'compile' to initialize groupnames; modify 'groups' method to allow > strings (names) in addition to integer indices] > > This ends up looking like your solution, but the relationship > between 'regs', groups(), and 'groupnames' is explicit. This > is useful because it increases the number of "fruitful > interactions". Well, there's nothing to stop you from writing a portable module, in std Python, that does exactly all that today. If you did that & distributed the module, and people liked it a lot, Guido might get interested in hacking a C version <grin>. > Improvement 2: > Add syntax to regular expressions so that groups can be named > in place, yielding the group dictionary. (This is a *big* > advantage over perl.) > > For example: > re = '[^0-9]*\(<number>[0-9]+\)[ \t]+\(<label>[A-Za-z_-.]+\)' > decode = regex.compile( re) > n, l = decode.groups( 'number', 'label') > > I like this idea, because then I can build complicated regular > expressions in substrings, and then catenate them together > into the final regular expression before compiling. It also > completely eliminates group-counting, and it provides a visual > indication of which groups are just for grouping, and which > are for substring extraction. Agree that _is_ nice. But again, it's something you _can_ do today, in your own Python module (in your compile method, you "just" need to analyze the pattern string before invoking regex.compile, stripping out the '<name>' portions and saving away the derived name->index dict; there's really no need to touch the current regex implementation, except in that it's likely you'll wind up using more sets of parens than regexmodule is currently compiled to handle). > But what python really needs are LALR(1) parser objects, don't you > think? Hard to say! I confess I came to UNIX(tm) late in life, & never did grasp the fascination with regexps. I find them awfully cryptic & clumsy as soon as they go beyond the trivial. E.g., here's one from python-mode.el, to match a Python line that opens a code block: \\([^#'\n\\]\\|'\\([^'\n\\]\\|\\\\.\\)*'\\|\\\\\n\\)*:\\([ \t]\\|\\\\\n\\)*\\(#.*\\)?$ I can't even read that anymore! Least not without a lot of tedious effort. A std parsing approach might be better after all (how many more desperate net msgs will we read asking how to capture the concept of nesting brackets via regexps <0.9 grin>?). But not sure: the only truly _pleasant_ pattern-matching language I've used is SNOBOL4, & even it was clumsy for dealing with left recursion. Suspect we agree that regexps aren't the right way to go for complex pattern-matching tasks. On the other hand, I do think they're fine for simple tasks, so maybe keeping them clusmy to use is doing most users a favor <0.9 grin>. > [guido] > I'm afraid the trouble with this one [tracy's '<name>' extension] is > that the syntax of Python regular expressions is defined by the GNU > Emacs regular expression package. Ya, but it's not an essential extension -- the <name> constructs are syntactic sugar that could be stripped out before the Emacs package is invoked. Not saying you _should_, just saying that it's not hard to do. > ... Is it really that hard to count occurrences of \(? Well, it _is_ error-prone: I remember when quoted strings were introduced into Fortran, and hearing "is it really that hard to count the number of characters in a Hollerith?" (hint: the answer is "no" <grin>). I think what it _does_ do is impose an unnatural implementation layer between the way we think of the problem & the way we need to code the solution. On the other hand, in those cases where regexps get so fancy that the need for counting parens goes above 3 (truly my _comfortable_ mental limit!), regexps probably aren't the right tool for the job anyway ... > ... > Would you folks settle for a recursive descent parser generator (like > the one used to build the Python parser)? That one I know how to > hack... I'd like to see someone suggest a specific interface, & code it up in Python, so we could get a feel for how it works in practice. In the meantime, I believe everyone agrees that a regex method supporting varargs "integer group names" would be a valuable extension -- right? mostly-just-thinking-out-loud-ly y'rs - tim Tim Peters tim@ksr.com not speaking for Kendall Square Research Corp Received: from mcsun.EU.net by charon.cwi.nl with SMTP id AA07047 (5.65b/3.8/CWI-Amsterdam); Tue, 23 Feb 1993 16:24:23 +0100 Received: by mcsun.EU.net via EUnet id AA25585 (5.65b/CWI-2.207); Tue, 23 Feb 1993 16:24:22 +0100 Received: from ghost.uunet.ca (via uunet.ca) by relay1.UU.NET with SMTP (5.61/UUNET-internet-primary) id AA19004; Tue, 23 Feb 93 10:23:55 -0500 Received: from snitor by mail.uunet.ca with UUCP id <9657(2)>; Tue, 23 Feb 1993 10:23:37 -0500 Received: from radium.sni.ca by snitor.sni.ca (5.61/smail2.5/07-11-92) id AA20019; Tue, 23 Feb 93 09:50:39 -0500 Received: by radium.sni.CA (5.61/smail2.5/02-09-92) id AA04624; Tue, 23 Feb 93 09:50:21 -0500 Date: Tue, 23 Feb 1993 09:50:21 -0500 From: tracy@snitor.sni.ca (Tracy Tims) Message-Id: <9302231450.AA04624@radium.sni.CA> To: tim@ksr.com Cc: python-list@cwi.nl In-Reply-To: Tim Peters's message of Tue, 23 Feb 1993 01:02:51 -0500 <9302230602.AA00153@kaos.ksr.com> Subject: Distributing programs and grouping modules. If I write a python program and it doesn't require any additional "independent" modules, then I can just bundle up the program and send it to someone, and they only have one item to install and maintain. If I write a regular expression module, and then use that in my programs, everyone who wants to use one of my programs will have to obtain and install my regular expression module as well. This becomes an arbitrarily large problem, because I could improve other python modules in the same way, and because other people could also write their own improvements. It has been my experience that the greater the degree of idiosyncracy in a program's environment (libraries, language extensions, etc, etc) the more difficult it will be to install and maintain the program. This is especially true if the environment into which the program is being installed is also idiosyncratic. Imagine, after a few years of code sharing with other python lovers, a single directory of python programs and modules which contained several distinct re-interpretations of regular expressions. Yuck. I suppose one could write a program "packager" that would perform a closure over "import" and then output the list of files containing the non-standard modules required for the program. Perhaps this points up a weakness in python. There is a good modularization mechanism, but the concept of 'program' and 'library' isn't yet well developed. Could this be handled by expanding the semantics of 'import' so that it would also scan for modules in subdirectories of directories on the path? If it did this, multi-module programs or programs with idiosyncratic support modules could be installed into their own subdirectories. (The import statement would need to be changed to do some variant of "first search the directory containing the module executing the 'import' statement" in order to disambiguate modules with the same name.) This is interesting to me, because most of my python scripts are multi-module. I even write my "shell-scripts" as modules, and I use a special module for finding and invoking them, so that all of the python programs in my bin look like this... #! /usr/local/bin/python import startscript The startscript module is sort of neat, because it knows whether or not the module is being run as a standalone command (and therefore main() should be called) or whether it is being imported interactively for debugging. (It also means that almost all of my python code is in .pyc files.) Tracy Received: from alpha.Xerox.COM by charon.cwi.nl with SMTP id AA09352 (5.65b/3.8/CWI-Amsterdam); Tue, 23 Feb 1993 18:23:27 +0100 Received: from eros.EuroPARC.Xerox.COM ([13.1.252.143]) by alpha.xerox.com with SMTP id <11720>; Tue, 23 Feb 1993 09:23:09 PST Received: by eros.EuroPARC.Xerox.COM with SMTP (5.65c/IDA-1.2.9) id AA00241; Tue, 23 Feb 1993 17:22:31 GMT Message-Id: <199302231722.AA00241@eros.EuroPARC.Xerox.COM> To: python-list@cwi.nl Subject: Re: Distributing programs and grouping modules. In-Reply-To: Your message of "Tue, 23 Feb 93 06:50:21 PST." <9302231450.AA04624@radium.sni.CA> Date: Tue, 23 Feb 1993 09:22:30 PST From: Fraser@europarc.xerox.com For what it's worth, I have this at the start of a couple of my programs: # This little bit of code helps find a module which isn't # in the usual place! It adds the directory part of ARGV[0] # and the standard unix path to the module search path. rundir = posixpath.split(sys.argv[0])[0] if rundir != '': sys.path.insert(0,rundir) sys.path = sys.path + string.splitfields(posix.environ['PATH'],':') Crude, but generally effective. Not as complete as your suggestion, though. Quentin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Quentin Stafford-Fraser Rank Xerox EuroPARC, I wish I was a little bug Cambridge, UK With hairs all round my tummy Tel: +44 223 341529 I'd jump into a honey pot Fax: +44 223 341510 And make my tummy gummy. Fraser@europarc.xerox.com Ogden Nash To: python-list Subject: formatted output From: Guido.van.Rossum@cwi.nl X-Organization: CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Mon, 08 Mar 1993 15:00:52 +0100 Sender: guido As you all know, formatted output isn't currently among Python's strong points. Here's an idea to fix it. Comments, please! - The binary operator '%' is overloaded with a new meaning: if its left argument is a string, the right argument can be any value, and the result is a string. - The outcome of "s % v" is informally defined as the string resulting from "sprintf(buf, s, v)" in C. - The outcome of "s % (v1, v2, ...)" is similarly defined as the result of "sprintf(buf, s, v1, v2, ...)". The net effect is that you can do things like >>> print '/%6d/%6g/%-6s/' % (300, 3.14, 'x') / 300/ 3.14/x / >>> But also >>> s = '/%6d/%6g/%-6s/' % (300, 3.14, 'x') >>> print s '/ 300/ 3.14/x /' >>> Complete error checking will of course ensure that mismatches between the format and the supplied values will raise exceptions rather than dump core or yield garbage. Possibly the range of values accepted by certain format codes will be richer than for C, e.g. %f and %g will work with integers, and some format codes will be identical, e.g. %hd, %d and %ld should make no difference. Arbitrary values can be formatted using '%s' % `value`. (That's reverse quotes around value.) I hope this concise description conveys my ideas (which are less than half an hour old at the moment I am writing this) sufficiently. Please send in your suggestions for alternatives! --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> PS. I'm sorry for not responding to some earlier messages, e.g. about program structure -- the issues raised there are certainly interesting, I'm just incredibly busy... Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA12764 (5.65b/3.8/CWI-Amsterdam); Mon, 8 Mar 1993 15:00:56 +0100 Received: by voorn.cwi.nl with SMTP id AA18613 (5.65b/3.8/CWI-Amsterdam); Mon, 8 Mar 1993 15:00:53 +0100 Message-Id: <9303081400.AA18613=guido@voorn.cwi.nl> To: python-list@cwi.nl Subject: formatted output From: Guido.van.Rossum@cwi.nl X-Organization: CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Mon, 08 Mar 1993 15:00:52 +0100 Sender: Guido.van.Rossum@cwi.nl As you all know, formatted output isn't currently among Python's strong points. Here's an idea to fix it. Comments, please! - The binary operator '%' is overloaded with a new meaning: if its left argument is a string, the right argument can be any value, and the result is a string. - The outcome of "s % v" is informally defined as the string resulting from "sprintf(buf, s, v)" in C. - The outcome of "s % (v1, v2, ...)" is similarly defined as the result of "sprintf(buf, s, v1, v2, ...)". The net effect is that you can do things like >>> print '/%6d/%6g/%-6s/' % (300, 3.14, 'x') / 300/ 3.14/x / >>> But also >>> s = '/%6d/%6g/%-6s/' % (300, 3.14, 'x') >>> print s '/ 300/ 3.14/x /' >>> Complete error checking will of course ensure that mismatches between the format and the supplied values will raise exceptions rather than dump core or yield garbage. Possibly the range of values accepted by certain format codes will be richer than for C, e.g. %f and %g will work with integers, and some format codes will be identical, e.g. %hd, %d and %ld should make no difference. Arbitrary values can be formatted using '%s' % `value`. (That's reverse quotes around value.) I hope this concise description conveys my ideas (which are less than half an hour old at the moment I am writing this) sufficiently. Please send in your suggestions for alternatives! --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> PS. I'm sorry for not responding to some earlier messages, e.g. about program structure -- the issues raised there are certainly interesting, I'm just incredibly busy... Replied: Thu, 11 Mar 1993 19:40:38 +0100 Replied: "peter@robots.oxford.ac.uk python-list" Received: from relay.surfnet.nl by charon.cwi.nl with SMTP id AA10722 (5.65b/3.8/CWI-Amsterdam); Wed, 10 Mar 1993 20:12:46 +0100 X400-Received: by mta relay.surfnet.nl in /PRMD=surf/ADMD=400net/C=nl/; Relayed; Wed, 10 Mar 1993 20:12:42 +0100 X400-Received: by /PRMD=surf/ADMD=400net/C=nl/; Relayed; Wed, 10 Mar 1993 20:13:30 +0100 X400-Received: by /PRMD=uk.ac/ADMD= /C=gb/; Relayed; Wed, 10 Mar 1993 20:12:02 +0100 X400-Received: by /PRMD=UK.AC/ADMD= /C=GB/; Relayed; Wed, 10 Mar 1993 20:12:07 +0100 X400-Received: by /PRMD=UK.AC/ADMD= /C=GB/; Relayed; Wed, 10 Mar 1993 20:12:04 +0100 X400-Received: by /PRMD=UK.AC/ADMD= /C=GB/; Relayed; Wed, 10 Mar 1993 20:12:04 +0100 Date: Wed, 10 Mar 1993 20:12:04 +0100 X400-Originator: peter%robots.oxford.ac.uk@prg.oxford.ac.uk X400-Recipients: python-list@cwi.nl X400-Mts-Identifier: [/PRMD=UK.AC/ADMD= /C=GB/;<9303101912.AA19607@thurio.robot] X400-Content-Type: P2-1984 (2) Content-Identifier: Matrix Module From: peter@robots.oxford.ac.uk Message-Id: <9303101912.AA19607@thurio.robots.ox.ac.uk> To: python-list@cwi.nl Subject: Matrix Module Hi, I'm thinking of doing some prototyping work which involve matrices, has anyone written a C or python module that allows the usual operations. If not, I'll have to use C :-( Thanks, Pete. Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA24035 (5.65b/3.8/CWI-Amsterdam); Thu, 11 Mar 1993 19:40:39 +0100 Received: by voorn.cwi.nl with SMTP id AA27929 (5.65b/3.8/CWI-Amsterdam); Thu, 11 Mar 1993 19:40:38 +0100 Message-Id: <9303111840.AA27929=guido@voorn.cwi.nl> To: peter@robots.oxford.ac.uk Cc: python-list@cwi.nl Subject: Re: Matrix Module In-Reply-To: Your message of "Wed, 10 Mar 1993 20:12:04 MET." <9303101912.AA19607@thurio.robots.ox.ac.uk> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Thu, 11 Mar 1993 19:40:38 +0100 Sender: Guido.van.Rossum@cwi.nl > I'm thinking of doing some prototyping work which involve >matrices, has anyone written a C or python module that allows >the usual operations. If not, I'll have to use C :-( I have a generalized array module (in C) that would store large arrays/matrices of floats quite a bit more efficiently than Python lists. I have also written a generalized N-dimensional array module (in Python) that you can use with the array module or with ordinary lists to implement matrix ops. The latter is really still under development. I should also warn you that "the usual ops on matrices" is a very ambiguous statement, if you need numerical operations like inversion you're out of luck. I wouldn't dream of writing numerical code in Python; nor would I dream of writing it in C; I would just link to an existing numerical library... Cheers, --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Fri, 12 Mar 1993 13:30:36 +0100 Replied: "Mats.Lidell@eua.ericsson.se (Mats Lidell) " Received: from mailgate.ericsson.se by charon.cwi.nl with SMTP id AA05854 (5.65b/3.8/CWI-Amsterdam); Fri, 12 Mar 1993 11:41:00 +0100 Received: from eua.ericsson.se by mailgate.ericsson.se (4.1/SMI-4.1-MAILGATE1.12) id AA25951; Fri, 12 Mar 93 11:40:56 +0100 Received: from ms.eua.ericsson.se by eua.ericsson.se (4.1/EUA-2.1) id AA11856; Fri, 12 Mar 93 11:40:55 +0100 Received: from euas66c31.eua.ericsson.se by ms.eua.ericsson.se (4.1/MS-2.1) id AA04729; Fri, 12 Mar 93 11:40:54 +0100 From: Mats.Lidell@eua.ericsson.se (Mats Lidell) Received: by euas66c31.eua.ericsson.se (4.1/client-1.3) id AA01151; Fri, 12 Mar 93 11:40:54 +0100 Date: Fri, 12 Mar 93 11:40:54 +0100 Message-Id: <9303121040.AA01151@euas66c31.eua.ericsson.se> To: python-list@cwi.nl Subject: Python and stdwin port to the Amiga? Comments: Hyperbole mail buttons accepted, v3.06. Hi Folks, Is there a port or is anyone planning to port python and/or stdwin to the Amiga? %% Mats To: Mats.Lidell@eua.ericsson.se (Mats Lidell) Subject: Re: Python and stdwin port to the Amiga? In-reply-to: Your message of "Fri, 12 Mar 1993 11:40:54 MET." <9303121040.AA01151@euas66c31.eua.ericsson.se> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Fri, 12 Mar 1993 13:30:36 +0100 Sender: guido >Is there a port or is anyone planning to port python and/or stdwin to >the Amiga? Porting Python (at least the core interpreter) should be a matter of having a decent C compiler. It is very portable code, for the most part (having been developed in part on a Mac with 16-bit ints), except the inherently OS-dependent parts like posixmodule.c (which is optional anyway). Porting STDWIN would require serious knowledge of the Amiga window system, you would have to write most code from scratch. I haven't heard of anyone attempting this yet. Cheers, --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Sat, 13 Mar 1993 12:01:41 +0100 Replied: "Ty Sarna <tsarna@endicor.com> " Received: from dptspd.sat.datapoint.com by charon.cwi.nl with SMTP id AA03773 (5.65b/3.8/CWI-Amsterdam); Sat, 13 Mar 1993 01:10:25 +0100 Received: from fezzik.endicor.com by dptspd.sat.datapoint.com with uucp (Smail3.1.28.1 #2) id m0nXJrN-000196C; Fri, 12 Mar 93 18:13 CST Received: by fezzik.endicor.com (TMA-1/EndiNet) id AA04135; Fri, 12 Mar 1993 17:50:39 CST Message-Id: <1993Mar12.175039.04135@fezzik.endicor.com> Date: Fri, 12 Mar 1993 17:50:39 CST Organization: Endicor Technologies, Inc., San Antonio, Texas From: Ty Sarna <tsarna@endicor.com> Subject: Re: Python and stdwin port to the Amiga? To: Mats.Lidell@eua.ericsson.se, python-list@cwi.nl > Hi Folks, > > Is there a port or is anyone planning to port python and/or stdwin to > the Amiga? A straight port is pretty easy, but to really be useful, the python interpreter needs to be in a .library and needs to be able to able to import other modules in .library's as ARexx does. This quickly get's complicated -- Python's implementation just doesn't fit well on the Amiga. Things like calling exit() from inside a shared library are a pain. I hacked on it some before DevCon but I've been very busy since and have half given up. If someone gets a nice port done I'd love to see it though. Lately I've been toying with ideas for a semi-pythonesque compiled language aimed particularly at high-performance concurrent network-distributed OO programming. -- Ty Sarna "Never let your sense of morals prevent you from tsarna@endicor.com doing what's right" -- Salvor Hardin Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA24210 (5.65b/3.8/CWI-Amsterdam); Thu, 18 Mar 1993 16:49:19 +0100 Received: by voorn.cwi.nl with SMTP id AA28866 (5.65b/3.8/CWI-Amsterdam); Thu, 18 Mar 1993 16:49:19 +0100 Message-Id: <9303181549.AA28866=guido@voorn.cwi.nl> To: python-list@cwi.nl Subject: MS-DOS executable available From: Guido.van.Rossum@cwi.nl X-Organization: CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Thu, 18 Mar 1993 16:49:18 +0100 Sender: Guido.van.Rossum@cwi.nl An MS-DOS executable of Python 0.9.8 is now available for anonymous from host ftp.cwi.nl, directory pub/python, file python.exe.Z. The file is compressed with UNIX compress. Use binary ftp transfer mode, as always. If you wait a couple of days, I hope this will be mirrored at the usual places (e.g. gatekeeper, uunet). Note that I can't really test this (although I've verified that it at least starts up correctly), but if you find any problems with it I'll try to forward them to the nice guy who built it for me. I'll keep the list informed on important known bugs. --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA22618 (5.65b/3.8/CWI-Amsterdam); Fri, 26 Mar 1993 13:13:05 +0100 Received: by voorn.cwi.nl with SMTP id AA08412 (5.65b/3.8/CWI-Amsterdam); Fri, 26 Mar 1993 13:13:05 +0100 Message-Id: <9303261213.AA08412=guido@voorn.cwi.nl> To: python-list@cwi.nl Subject: Mutable objects as mapping keys From: Guido.van.Rossum@cwi.nl X-Organization: CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Fri, 26 Mar 1993 13:13:04 +0100 Sender: Guido.van.Rossum@cwi.nl It's mighty quiet on the python mailing list these days, so I suppose you are all busy writing Python scripts for the next obfuscated Python competition :-) Seriously, I have a design problem. I'm (at last!) writing code that will support arbitrary values as keys for dictionaties. So you will at last be able to create a dictionary with numeric keys, or with tuples containing strings and numbers, etc. However, there's a problem with allowing lists! Since a list can be modified, its value can be changed later. E.g. if I create a list a = [1, 2] and use it as a dictionary key, e.g. d = {a: 'foobar'}, and now I call a.append(3), then the dictionary object is in trouble: it has saved a *pointer* to a as the key, so the value of d has suddenly changed to {[1, 2, 3]: 'foobar'}. This is not what you want! (I think :-) Moreover, the dictionary implementation uses hashing of the keys, and the entry will still be located at the hash value for [1, 2]. One way out seems to be to make a deep copy of the key value (if it contains a mutable object), but this is slow. You also have to make another deep copy when the caller asks for the keys() of the dictionary, otherwise there would still be a way to subvert the value of a key... Also note that there may be a list hidden deep inside a tuple of tuples, so at least some of the the deep copying overhead is present even when no lists are actually used as keys! My current solution is to disallow mutable objects as dictionary keys, unless object comparison is defined as pointer comparison for that particular object (e.g. files). This makes dictionaries less general, since lists (or dictionaries!) can't be used as keys. I can imagine that this is sometimes a drag, but I don't think the performance penalty of copying is acceptable, nor do I trust the users of dictionaries never to accidentally modify a list they have used as a key. My questions to the general public are: (1) do you think that disallowing lists as keys is a big drawback? (2) would you accept the performance penalty of always deep copying lists used as keys? (2a) when using lists (2b) when not using lists! (3) do you happen to have another implementation idea? --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Fri, 26 Mar 1993 14:29:08 +0100 Replied: ""Clint Jeffery" <cjeffery@cs.arizona.edu> python-list" Received: from optima.cs.arizona.edu by charon.cwi.nl with SMTP id AA23902 (5.65b/3.8/CWI-Amsterdam); Fri, 26 Mar 1993 14:20:41 +0100 Received: from chuckwalla.cs.arizona.edu by optima.cs.arizona.edu (5.65c/15) via SMTP id AA29567; Fri, 26 Mar 1993 06:20:38 MST Date: Fri, 26 Mar 1993 06:20:37 MST From: "Clint Jeffery" <cjeffery@cs.arizona.edu> Message-Id: <199303261320.AA29722@chuckwalla.cs.arizona.edu> Received: by chuckwalla.cs.arizona.edu; Fri, 26 Mar 1993 06:20:37 MST To: Guido.van.Rossum@cwi.nl In-Reply-To: Guido.van.Rossum@cwi.nl's message of Fri, 26 Mar 1993 13:13:04 +0100 <9303261213.AA08412=guido@voorn.cwi.nl> Subject: Mutable objects as mapping keys (1) do you think that disallowing lists as keys is a big drawback? Its not a practical drawback, it is merely a drawback in "elegance". It seems cleaner to do this than to do the deep copy thing though. (2) would you accept the performance penalty of always deep copying lists used as keys? (2a) when using lists (2b) when not using lists! How deep? Does Python allow cycles in such structures? (3) do you happen to have another implementation idea? Icon allows structure keys, and such keys can change -- lists have an associated serial number that is used for hashing since neither the contents nor the pointer to the list are safe to hash on. It is fast, cheap, and consistent with the mutable nature of (Icon) lists...but maybe Python lists are qualitatively different than Icon lists. Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA24171 (5.65b/3.8/CWI-Amsterdam); Fri, 26 Mar 1993 14:29:09 +0100 Received: by voorn.cwi.nl with SMTP id AA08971 (5.65b/3.8/CWI-Amsterdam); Fri, 26 Mar 1993 14:29:08 +0100 Message-Id: <9303261329.AA08971=guido@voorn.cwi.nl> To: "Clint Jeffery" <cjeffery@cs.arizona.edu> Cc: python-list@cwi.nl Subject: Re: Mutable objects as mapping keys In-Reply-To: Your message of "Fri, 26 Mar 1993 06:20:37 MET." <199303261320.AA29722@chuckwalla.cs.arizona.edu> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Fri, 26 Mar 1993 14:29:08 +0100 Sender: Guido.van.Rossum@cwi.nl "Clint Jeffery" <cjeffery@cs.arizona.edu> writes: > (1) do you think that disallowing lists as keys is a big drawback? > >Its not a practical drawback, it is merely a drawback in "elegance". >It seems cleaner to do this than to do the deep copy thing though. That's what I though too. > (2) would you accept the performance penalty of always deep copying > lists used as keys? (2a) when using lists (2b) when not using lists! > >How deep? Does Python allow cycles in such structures? Oops, you're right, it is possible to create lists containing circular references. This would make deep-copying even less practical. (Circular references cause other problems too, e.g. can't be printed or dumped through "marshal", but they can be useful nevertheless, and checking would be problematic.) > (3) do you happen to have another implementation idea? > >Icon allows structure keys, and such keys can change -- lists have an >associated serial number that is used for hashing since neither the >contents nor the pointer to the list are safe to hash on. It is fast, >cheap, and consistent with the mutable nature of (Icon) lists...but >maybe Python lists are qualitatively different than Icon lists. In Python using the pointer as a hash value would be safe (since it can't change), but this would make lists almost as useless keys: after d = {[1, 2]: 2; [1, 2, 3]: 3} the test d.has_key([1, 2]) would yield false, since the [1, 2] used here is a different instance than the [1, 2] used as key. --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from inesc.inesc.pt by charon.cwi.nl with SMTP id AA25367 (5.65b/3.8/CWI-Amsterdam); Fri, 26 Mar 1993 15:51:14 +0100 Received: from sabrina-2.inesc.pt by inesc.inesc.pt with SMTP; id AA09018 (5.65a/Ultrix4.0); Fri, 26 Mar 93 15:51:35 +0100 Received: from cretina.inesc.pt by sabrina.inesc.pt (4.1/SunOS4.1.1) id AA07401; Fri, 26 Mar 93 15:50:48 +0100 Date: Fri, 26 Mar 93 15:50:48 +0100 From: pereira@sabrina.inesc.pt (Jose M. Pereira) Message-Id: <9303261450.AA07401@sabrina.inesc.pt> Received: by cretina.inesc.pt (4.1/SMI-4.1) id AA04230; Fri, 26 Mar 93 15:50:45 +0100 To: Guido.van.Rossum@cwi.nl Cc: python-list@cwi.nl Subject: Mutable objects as mapping keys In-Reply-To: <9303261213.AA08412=guido@voorn.cwi.nl> References: <9303261213.AA08412=guido@voorn.cwi.nl> Guido van Rossum writes: > > My questions to the general public are: > > (1) do you think that disallowing lists as keys is a big drawback? Not really. I can't even think of an obvious example where it would be useful... > > (2) would you accept the performance penalty of always deep copying > lists used as keys? (2a) when using lists (2b) when not using > lists! One of the biggest advantages of using dictionaries is the efficiency of search (hash tables, etc...). So, I would say no at least in case (2b). > > (3) do you happen to have another implementation idea? Unfortunately, I must throw another "no" in here... ---------------------------------------------------------------------- Jose' Pereira INESC (Inst. Eng. Sistemas e Computadores) R. Alves Redol 9, 6. 1000 Lisboa, PORTUGAL. Phone.: +351 1 3100225 Fax...: +351 1 525843 e-mail: jmp@inesc.pt PSI...: %(0268)004010314::inesc::jmp Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA29485 (5.65b/3.8/CWI-Amsterdam); Fri, 26 Mar 1993 19:06:06 +0100 Received: from server.cs.virginia.edu by uvaarpa.virginia.edu id aa15864; 26 Mar 93 12:23 EST Received: from bodhi.cs.Virginia.EDU by uvacs.cs.virginia.edu (4.1/5.1.UVA) id AA03321; Fri, 26 Mar 93 12:23:12 EST Posted-Date: Fri, 26 Mar 93 12:23:11 EST Return-Path: <kph2q@bodhi.cs.Virginia.EDU> Received: by bodhi.cs.Virginia.EDU (4.1/SMI-2.0) id AA11832; Fri, 26 Mar 93 12:23:11 EST Date: Fri, 26 Mar 93 12:23:11 EST From: Kenneth Hinckley <kph2q@bodhi.cs.virginia.edu> Message-Id: <9303261723.AA11832@bodhi.cs.Virginia.EDU> To: Guido.van.Rossum@cwi.nl Subject: Re: Mutable objects as mapping keys References: <9303261213.AA08412=guido@voorn.cwi.nl> Guido.van.Rossum@cwi.nl writes: | My questions to the general public are: | (1) do you think that disallowing lists as keys is a big drawback? No, especially since having lists as keys is likely to be (1) confusing to the programmer and (2) a probable source of bugs or undesirable interactions with other language features. | (2) would you accept the performance penalty of always deep copying | lists used as keys? (2a) when using lists (2b) when not using lists! (2a) Yes (2b) Absolutely not! Using lists as keys is probably handy about one time out of a hundred, and the other 99 times you shouldn't have to pay for the cost. | (3) do you happen to have another implementation idea? You might consider having an immutable list type, i.e. a list that doesn't support .append(), etc. Of course, now you have the problem of specifying whether a given list is mutable or immutable; python's aversion to static type declarations might make this idea impractical. Perhaps another way to approach it would be to have a .lock() method for lists. When a list is 'locked', it is immutable-- trying to call a method that changes the list would raise an exception. Trying to place an unlocked list in a dictionary would also raise an exception. Hope some of this is vaguely useful. Ken Replied: Sat, 27 Mar 1993 10:16:11 +0100 Replied: "manny@tcomeng.com (Manny Juan) " Received: from tcomeng.com by charon.cwi.nl with SMTP id AA05354 (5.65b/3.8/CWI-Amsterdam); Sat, 27 Mar 1993 08:47:28 +0100 Received: by tcomeng.com (AIX 3.2/UCB 5.64/4.03) id AA58290; Fri, 26 Mar 1993 23:45:08 -0800 From: manny@tcomeng.com (Manny Juan) Message-Id: <9303270745.AA58290@tcomeng.com> Subject: python (msdos) docs? libraries? To: python-list@cwi.nl Date: Fri, 26 Mar 1993 23:45:08 -0800 (PST) X-Mailer: ELM [version 2.4 PL21] Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-Length: 188 where can i find the following? (in ascii) tutorial for python for ms-dos docs / language ref for ms-dos libraries/modules/support files for python for ms-dos thanks manny@tcomeng.COM To: manny@tcomeng.com (Manny Juan) Subject: Re: python (msdos) docs? libraries? In-reply-to: Your message of "Fri, 26 Mar 1993 23:45:08 MET." <9303270745.AA58290@tcomeng.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Sat, 27 Mar 1993 10:16:12 +0100 Sender: guido >where can i find the following? (in ascii) > >tutorial for python for ms-dos >docs / language ref for ms-dos >libraries/modules/support files for python for ms-dos You will have to ftp the UNIX source distribution and extract them from there. The variable sys.builtin_module_names lists the built-in modules -- this will tell you which parts of the library reference to skip. --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Mon, 29 Mar 1993 18:36:04 +0100 Replied: "Tim Peters <tim@ksr.com> python-list@cwi.nl" Received: from hopscotch.ksr.com by charon.cwi.nl with SMTP id AA02812 (5.65b/3.8/CWI-Amsterdam); Mon, 29 Mar 1993 05:24:53 +0100 Received: from ksr.com (frankenstein.ksr.com) by hopscotch.ksr.com with SMTP id AA23011; Sun, 28 Mar 1993 23:24:41 -0500 Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA11299; Sun, 28 Mar 93 23:25:04 EST Received: by kaos.ksr.com (4.1/KSR-2.0) id AA28662; Sun, 28 Mar 93 23:25:02 EST Message-Id: <9303290425.AA28662@kaos.ksr.com> To: python-list@cwi.nl Subject: Re: Mutable objects as mapping keys Date: Sun, 28 Mar 93 23:24:56 EST From: Tim Peters <tim@ksr.com> > if I create a list a = [1, 2] and use it as a dictionary key, e.g. d = > {a: 'foobar'}, and now I call a.append(3), then the dictionary object > is in trouble: it has saved a *pointer* to a as the key, so the value > of d has suddenly changed to {[1, 2, 3]: 'foobar'}. This is not what > you want! (I think :-) Well, _I_ can live with that <smile>. In fact, if I think of a dictionary as mapping _objects_ to objects, this is the behavior I expect, since a.append(3) doesn't change a's identity _as an object_. It's only confusing if I think of a dictionary as mapping _values_ to objects. Both views can be useful, & I suspect the best thing to do is to compromise: > ... > In Python using the pointer as a hash value would be safe (since it > can't change), but this would make lists almost useless as keys: after > > d = {[1, 2]: 2; [1, 2, 3]: 3} > > the test > > d.has_key([1, 2]) > > would yield false, since the [1, 2] used here is a different instance > than the [1, 2] used as key. The same is true in Icon, where "dictionaries" are called "tables", and can be indexed by anything (strings, lists, other tables, pieces of code, ... anything). E.g., kaos 36= cat t.icn procedure main() local t, x t := table() # a table, mapping anything to anything x := [1,2] # a list t[x] := 5 if /t[x] then write( "x not in table" ) else write( "x associated with ", t[x] ) push( x, 3 ) # x becomes [1,2,3] if /t[x] then write( "x not in table" ) else write( "x associated with ", t[x] ) x := [1,2,3] # same _value_ as x, but different object if /t[x] then write( "x not in table" ) else write( "x associated with ", t[x] ) end kaos 37= it -s t -x x associated with 5 x associated with 5 x not in table kaos 38= This doesn't stop Icon's tables from being useful. E.g., the Icon Program Library uses this feature many times, especially in routines to provide printable representations for arbitrary (including cyclic) data structures. In fact, "pointer equality" semantics for structured objects are crucial to making that kind of routine easy to write. I can't remember the specifics now, but I know that in Icon I once even had a "good use" for a table that was itself indexed by tables (some hairy graph algorithm ... and again it was crucial that the mapping not be affected by changes _to_ the tables used as indices). The best approach is probably a philosophical mix: use "value equality" for an index with type string or number or Null, and "object equality" for everything else (I guess Null fits in either branch). The distinction here is best viewed as being between, say, "atomic objects" (those like numbers & strings with no internally visible structure) and "structured objects" (those, like lists & tuples, built out of simpler types). Probably best if d[2] and d[2L] and d[2.0] mapped to different things too (so that "value equality" is sensitive to type as well as to value). I think I just recast Icon's rules into Pythonese there. It's a pretty good way to go in practice, & I really don't know of a better one. Perl carries value equality to an extreme, so that after $dict{1} = 'hi'; $dict{1} and $dict{'1'} and $dict{cos(0.0)} all refer to 'hi' too. _That_ can be surprising. thinking-this-is-one-of-those-happy-cases-where-the-easiest-implementation- is-also-the-most-efficient-&-the-most-useful-ly y'rs - tim Tim Peters tim@ksr.com not speaking for Kendall Square Research Corp Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA12375 (5.65b/3.8/CWI-Amsterdam); Mon, 29 Mar 1993 12:28:05 +0100 Received: by voorn.cwi.nl with SMTP id AA16226 (5.65b/3.8/CWI-Amsterdam); Mon, 29 Mar 1993 12:28:04 +0100 Message-Id: <9303291128.AA16226=guido@voorn.cwi.nl> To: python-list@cwi.nl Subject: tzparse.py From: Guido.van.Rossum@cwi.nl X-Organization: CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Mon, 29 Mar 1993 12:28:04 +0100 Sender: Guido.van.Rossum@cwi.nl Now daylight saving time has arrived (at least in Europe), I've discovered a bug in tzparse.py. Please apply this patch if your "mclock" is now running two hours behind: =================================================================== RCS file: /ufs/guido/CVSROOT/python/lib/tzparse.py,v retrieving revision 1.1 diff -c -1 -r1.1 tzparse.py *** 1.1 1992/10/18 17:09:58 --- tzparse.py 1993/03/29 11:23:50 *************** *** 42,44 **** timezone = tzparams[1] * 3600 ! altzone = timezone + 3600 daylight = 1 --- 42,44 ---- timezone = tzparams[1] * 3600 ! altzone = timezone - 3600 daylight = 1 --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> To: python-list Subject: tzparse.py From: Guido.van.Rossum@cwi.nl X-Organization: CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Mon, 29 Mar 1993 12:28:04 +0100 Sender: guido Now daylight saving time has arrived (at least in Europe), I've discovered a bug in tzparse.py. Please apply this patch if your "mclock" is now running two hours behind: =================================================================== RCS file: /ufs/guido/CVSROOT/python/lib/tzparse.py,v retrieving revision 1.1 diff -c -1 -r1.1 tzparse.py *** 1.1 1992/10/18 17:09:58 --- tzparse.py 1993/03/29 11:23:50 *************** *** 42,44 **** timezone = tzparams[1] * 3600 ! altzone = timezone + 3600 daylight = 1 --- 42,44 ---- timezone = tzparams[1] * 3600 ! altzone = timezone - 3600 daylight = 1 --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA09843 (5.65b/3.8/CWI-Amsterdam); Mon, 29 Mar 1993 19:36:06 +0200 Received: by voorn.cwi.nl with SMTP id AA17494 (5.65b/3.8/CWI-Amsterdam); Mon, 29 Mar 1993 18:36:05 +0100 Message-Id: <9303291736.AA17494=guido@voorn.cwi.nl> To: Tim Peters <tim@ksr.com> Cc: python-list@cwi.nl Subject: Re: Mutable objects as mapping keys In-Reply-To: Your message of "Sun, 28 Mar 1993 23:24:56 MET." <9303290425.AA28662@kaos.ksr.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Mon, 29 Mar 1993 18:36:04 +0100 Sender: Guido.van.Rossum@cwi.nl Tim Peters writes: >Well, _I_ can live with that <smile>. In fact, if I think of a >dictionary as mapping _objects_ to objects, this is the behavior I >expect, since a.append(3) doesn't change a's identity _as an object_. >It's only confusing if I think of a dictionary as mapping _values_ to >objects. Both views can be useful, & I suspect the best thing to do is >to compromise: [Icon example deleted] >The best approach is probably a philosophical mix: use "value equality" >for an index with type string or number or Null, and "object equality" >for everything else (I guess Null fits in either branch). The >distinction here is best viewed as being between, say, "atomic objects" >(those like numbers & strings with no internally visible structure) and >"structured objects" (those, like lists & tuples, built out of simpler >types). Probably best if d[2] and d[2L] and d[2.0] mapped to different >things too (so that "value equality" is sensitive to type as well as to >value). > >I think I just recast Icon's rules into Pythonese there. It's a pretty >good way to go in practice, & I really don't know of a better one. You seem to have a minority viewpoint here :-). I would argue that in Python, in most cases, value semantics are more useful. The reason is probably that value semantics abound elsewhere in Python: e.g. (x == y) compares values, not object identities, and so does the test (x in y) where y is a list: indeed (0 in [0.0]) is true. This makes it unattractive to use object semantics for dictionary keys, since it would break a useful invariant: if x in m.keys(), m.has_key(x) is true and m[x] is uniquely defined. In Python (I don't know about Icon) it is always possible to force object semantics by wrapping a value in a class instance. The reverse is not true. Since most opaque object types in Python have object semantics anyway (e.g. if you open the same file twice, the open file objects compare different), the only types for which choosing object or value semantics makes a difference are tuples, lists and dictionaries (yes, using dictionaries as keys can make sense -- e.g. when calculating functions over graphs represented as dictionaries). I strongly believe that tuples should be treated as values, not as objects. Consider a function of two arguments that is rather expensive to calculate. This function could maintain a dictionary of previously calculated function values and return values from there if available, like this: known = {} def f(a, b): if known.has_key((a,b)): return known[(a, b)] x = real_f(a, b) known[(a, b)] = x return x This sounds like a useful general mechanism to have. It also pleads for identifying numerical keys which compare equal (not, of course, taking it to the extreme that Perl does -- after all Python has a form of strong typing), so f(1, 2) will reuse a known value for f(1.0, 2.0). It is true that this doesn't work for your example of a library routine that needs to be able to traverse *arbitrary* circular data structures; but a built-in function returning the address of an object as integer would be a good alternative (so you can still build a dictionary keyed on object identity). Regarding lists and dictionaries, the problem is this: if possible I would like to support value semantics for those, but the implementation makes this too difficult. If I choose object semantics, programs expecting value semantics (and exploiting the invariants explained above) break unexpectedly. Therefore I choose (and have already implemented :-) not to support these types as dictionary keys, so that at least the problem isn't obscured. The whole exercise does point out a problem with value semantics for mutable objects, but I still think Python uses a reasonable compromise here, even if it is different from Icon's... Thanks for reacting anyway, --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from hopscotch.ksr.com by charon.cwi.nl with SMTP id AA09825 (5.65b/3.8/CWI-Amsterdam); Tue, 30 Mar 1993 07:00:12 +0200 Received: from ksr.com (frankenstein.ksr.com) by hopscotch.ksr.com with SMTP id AA13000; Mon, 29 Mar 1993 23:59:55 -0500 Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA21333; Tue, 30 Mar 93 00:00:19 EST Received: by kaos.ksr.com (4.1/KSR-2.0) id AA15740; Tue, 30 Mar 93 00:00:11 EST Message-Id: <9303300500.AA15740@kaos.ksr.com> To: Guido.van.Rossum@cwi.nl Subject: Re: Mutable objects as mapping keys Cc: python-list@cwi.nl Date: Tue, 30 Mar 93 00:00:10 EST From: Tim Peters <tim@ksr.com> > [guido] > [much cogent explanation deleted, some reproduced below] > ... but I still think Python uses a reasonable compromise here, even if > it is different from Icon's... I think it's reasonable too! There are advantages to all these schemes. I was particularly impressed by your arguments about the way "value semantics" are used in other parts of Python, something I didn't consider. It is the case that Icon uses a specific mix of "value" and "pointer" rules for dictionary resolution, but Icon also uses that same mix of rules in its other comparison contexts (membership testing, its "===" equality predicate, selecting which "case" clause applies). On third thought I'm convinced this kind of consistency is worth more than anything else. > I strongly believe that tuples should be treated as values, not as > objects. Consider a function of two arguments that is rather > expensive to calculate. This function could maintain a dictionary of > previously calculated function values and return values from there if > available, like this: > > known = {} > def f(a, b): > if known.has_key((a,b)): return known[(a, b)] > x = real_f(a, b) > known[(a, b)] = x > return x Just noting that it's easy enough to fake given object semantics too. E.g., assuming a & b are numbers & Python's dictionaries have been extended to support indexing by numbers: known = {} def f(a,b): if known.has_key(a): a_vals = known[a] if a_vals.has_key(b): return a_vals[b] else: known[a] = a_vals = {} a_vals[b] = x = real_f(a, b) return x For this probably-common kind of use, I sure agree that value semantics allow a simpler solution (really, there's no need to trot out a function with three arguments <grin>). > ... > It is true that this doesn't work for your example of a library > routine that needs to be able to traverse *arbitrary* circular data > structures; but a built-in function returning the address of an object > as integer would be a good alternative (so you can still build a > dictionary keyed on object identity). Agreed again -- so how about adding that function <smile>? > Regarding lists and dictionaries, the problem is this: if possible I > would like to support value semantics for those, but the implementation > makes this too difficult. That's cool. I think we agree there _are_ clear uses for lists & dicts, as dict indices, provided object semantics are used. I think we agree too (me belatedly) that value semantics are more natural for Python. But I'm _not_ sure value semantics for lists & dicts, as dict indices, would be useful enough to be worth the pain of implementing. I do note that various LISPs implement dictionaries as "association lists", and that the usual access function "assoc" uses the "equal" predicate to see whether a key is present; and "equal" does usually compare deep structure (with undefined behavior in the presence of loops). Any LISP'ers out there who think that's important to do? can't-say-i've-seen-it-used!-ly y'rs - tim Tim Peters tim@ksr.com not speaking for Kendall Square Research Corp Received: from relay.surfnet.nl by charon.cwi.nl with SMTP id AA06360 (5.65b/3.8/CWI-Amsterdam); Fri, 2 Apr 1993 15:39:27 +0200 X400-Received: by mta relay.surfnet.nl in /PRMD=surf/ADMD=400net/C=nl/; Relayed; Fri, 2 Apr 1993 15:38:20 +0200 X400-Received: by /PRMD=surf/ADMD=400net/C=nl/; Relayed; Fri, 2 Apr 1993 15:39:02 +0200 X400-Received: by /PRMD=uk.ac/ADMD= /C=gb/; Relayed; Fri, 2 Apr 1993 15:20:05 +0200 X400-Received: by /PRMD=UK.AC/ADMD= /C=GB/; Relayed; Fri, 2 Apr 1993 15:19:53 +0200 Date: Fri, 2 Apr 1993 15:19:53 +0200 X400-Originator: bevan@computer-science.manchester.ac.uk X400-Recipients: python-list@cwi.nl X400-Mts-Identifier: [/PRMD=UK.AC/ADMD= /C=GB/;<9304021319.AA14516@panda.cs.man] X400-Content-Type: P2-1984 (2) Content-Identifier: Re: Mutable o... From: Stephen J Bevan <bevan@computer-science.manchester.ac.uk> Message-Id: <9304021319.AA14516@panda.cs.man.ac.uk> To: python-list@cwi.nl References: <9303300500.AA15740@kaos.ksr.com> Subject: Re: Mutable objects as mapping keys >>>>> On Tue, 30 Mar 93 00:00:10 EST, Tim Peters <tim@ksr.com> wrote: Tim> I do note that various LISPs implement dictionaries as "association Tim> lists", and that the usual access function "assoc" uses the "equal" Tim> predicate to see whether a key is present; and "equal" does usually Tim> compare deep structure (with undefined behavior in the presence of Tim> loops). Scheme currently has "member" which does the above and "memq" which uses pointer equality. Tim> Any LISP'ers out there who think that's important to do? This lisper prefers to let the user decide allow a user defined comparision function to be used. bevan Replied: Tue, 13 Apr 1993 10:29:29 +0200 Replied: "Fraser@europarc.xerox.com python-list" Received: from alpha.Xerox.COM by charon.cwi.nl with SMTP id AA18597 (5.65b/3.8/CWI-Amsterdam); Tue, 13 Apr 1993 10:20:18 +0200 Received: from eros.EuroPARC.Xerox.COM ([13.1.252.143]) by alpha.xerox.com with SMTP id <11599>; Tue, 13 Apr 1993 01:19:56 PDT Received: by eros.EuroPARC.Xerox.COM with SMTP (5.65c/IDA-1.2.9) id AA14708; Tue, 13 Apr 1993 09:19:37 +0100 Message-Id: <199304130819.AA14708@eros.EuroPARC.Xerox.COM> To: guido@cwi.nl Subject: embedding python Date: Tue, 13 Apr 1993 01:19:36 PDT From: Fraser@europarc.xerox.com Guido, I'm addressing this to you, as the person most likely to have the answer, but could you forward it to python-list if that's more appropriate. There is good documentation for extending python, but only a brief mention of embedding it in other applications. Have I missed anything? Are there guidelines for doing this? Have many people done it? Is it just a case of calling routines in pythonrun.h? Thanks, Quentin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Quentin Stafford-Fraser Rank Xerox EuroPARC, Some primal termite knocked on wood Cambridge, UK And tasted it, and found it good. Tel: +44 223 341529 And that is why your cousin May Fax: +44 223 341510 Fell through the parlour floor today. Fraser@europarc.xerox.com Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA18878 (5.65b/3.8/CWI-Amsterdam); Tue, 13 Apr 1993 10:29:30 +0200 Received: by voorn.cwi.nl with SMTP id AA22953 (5.65b/3.8/CWI-Amsterdam); Tue, 13 Apr 1993 10:29:30 +0200 Message-Id: <9304130829.AA22953=guido@voorn.cwi.nl> To: Fraser@europarc.xerox.com Cc: python-list@cwi.nl Subject: Re: embedding python In-Reply-To: Your message of "Tue, 13 Apr 1993 01:19:36 MDT." <199304130819.AA14708@eros.EuroPARC.Xerox.COM> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Tue, 13 Apr 1993 10:29:29 +0200 Sender: Guido.van.Rossum@cwi.nl (This may be of general importance, hence the cc: to the list --Guido) Quentin Fraser writes: >There is good documentation for extending python, but only a brief mention >of embedding it in other applications. Have I missed anything? At the time I wrote that documentation it hadn't been done yet but the code was designed to make it very simple. >Are there guidelines for doing this? Not yet. As it's so simple, they follow below... >Have many people done it? At least one company has done it (for a GUI builder), one university (for a VR system), and one person in my building (for an OO multimedia system). There may be more... >Is it just a case of calling routines in pythonrun.h? Basically, yes. If you look at pythonmain.c, you'll see in what order things have to be initialized: initargs(&argc, &argv); initall(); setpythonargv(argc-optind, argv+optind); /* optind is the index of the script name in argv */ After this you are free to call any of the run* functions or call_object() any time you like (or anything else that's available to extensions). --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA00945 (5.65b/3.8/CWI-Amsterdam); Wed, 14 Apr 1993 19:16:44 +0200 Received: from eng2.sequent.com by gateway.sequent.com (5.61/1.34) id AA27943; Wed, 14 Apr 93 10:17:20 -0700 Received: by eng2.sequent.com (5.65/1.34) id AA04184; Wed, 14 Apr 93 10:16:38 -0700 Message-Id: <9304141716.AA04184@eng2.sequent.com> To: python-list@cwi.nl Subject: Output disappears when using interrupt key Priority: Normal Precedence: first-class Organization: Sequent Computer Systems, Inc. Service Technology - MailStop: WIL2-610 15450 S.W. Koll Parkway Beaverton, OR 97006-6063 X-Phone: (503) 578-4404 X-Fax: (503) 578-4540 X-Uucp: ...!uunet!sequent!jaap X-Internet: jaap@sequent.com X-Face: C4Cnai$>Eja5I6Vq?(gdN#SXX#`-XgAnmUn&e54sx7@1>q@vkrd_XnH![P>w.:7IJJ;{Bts WJd)u&G!V}0OR?2o5cUgIY}.T{g]PMC=*~]3n_t)S-ZkC(WG}3:#hcA6Oazx:}yc&k,hsF7D},7x>l nyfRjO7$@]fHBN>aC9-M3pKfbYHiy!PWD{_bx~fo})b4tU.;Ao%x[upCI, Date: Wed, 14 Apr 93 10:16:37 PDT From: Jaap Vermeulen <jaap@sequent.com> Hi, I'm seeing the following anomaly. When executing the following statements: import sys try: sys.stdin.readline() except: print 'OK' and generating a keyboard interrupt while readline() is waiting for input, will *not* print the 'OK' on my system. However, the following works: import sys, time try: sys.stdin.readline() except: time.millisleep(300); print 'OK' Here I will see OK after a keyboard interrupt while readline() is waiting for input. My question is: is this platform specific? Do other people experience the same problem? Any other words of wisdom? Thanks, -Jaap- -- Jaap Vermeulen +--------------------------+ | Sequent Computer Systems | Internet : jaap@sequent.com | Beaverton, Oregon | Uucp : ...uunet!sequent!jaap +--------------------------+ Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA03394 (5.65b/3.8/CWI-Amsterdam); Wed, 14 Apr 1993 20:39:58 +0200 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa20575; 14 Apr 93 14:39 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA75886; Wed, 14 Apr 1993 14:39:39 -0400 Date: Wed, 14 Apr 1993 14:39:39 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199304141839.AA75886@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: Jaap Vermeulen <jaap@sequent.com> Subject: Re: Output disappears when using interrupt key Cc: python-list@cwi.nl xOn Apr 14, 10:16, Jaap Vermeulen wrote: > > I'm seeing the following anomaly. When executing the following > statements: > > import sys > try: sys.stdin.readline() > except: print 'OK' > > and generating a keyboard interrupt while readline() is waiting for > input, will *not* print the 'OK' on my system. > > [ ... alternate example deleted ] > > My question is: is this platform specific? Do other people experience > the same problem? Any other words of wisdom? > On my system ( IBM AIX 3.2 ; python sys.version '0.9.7 (DEC 20 1992)' ) the above does not seem to catch the keyboard interrupt until after a newline. But when it does get a newline, it does do the except clause. [ I also just tried SunOS 4.1 python sys.version 0.9.4 and got the same results. ] >>> def try1(): ... try: sys.stdin.readline() ... except: print ' -OK.' ... >>> try1() '\012' >>> try1() ^C^C^C^C^Cxxx -OK. # ^ <return-key> hit after several control-C and "x"'s "aaaa^Cbbbb\n" does the same. I would have expected that it should catch the first ^C right away, but it seems to take an interrupt in a new-line terminated string to cause the exception. I don't know where the problem is ( or what the expected behaviour actually should be ) but I know stdio is prone to some odd behaviour when used in signal catchers, etc. Your post caught my eye because I had been looking at some similar-but-different problems. I am evaluating the 'sfio' package from netlib@research.att.com. [ Guido ( and others to whom it may concern): - you may want to take a look at sfio. It fixes some of the stdio problems ( like interrupted i/o, allowing writes to read-opened files, etc. ). There is a different API that stdio-lib, with some extra neat features, but there is a stdio emulation package for backwards source compatability. I haven't used it enough yet to give a report. ] -Steve Majewski (804-982-0831) <sdm7g@Virginia.EDU> -Univ. of Virginia Department of Molecular Physiology and Biological Physics Replied: Thu, 15 Apr 1993 01:02:29 +0200 Replied: ""Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Jaap Vermeulen <jaap@sequent.com>, python-list@cwi.nl" Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA03907 (5.65b/3.8/CWI-Amsterdam); Wed, 14 Apr 1993 20:59:37 +0200 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa23640; 14 Apr 93 14:59 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA73944; Wed, 14 Apr 1993 14:59:21 -0400 Date: Wed, 14 Apr 1993 14:59:21 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199304141859.AA73944@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: Jaap Vermeulen <jaap@sequent.com> Subject: Re: Output disappears when using interrupt key Cc: python-list@cwi.nl Another curious "feature": # file try2.py import sys def try2(): L = '######initial#string######' try: L = sys.stdin.readline() print '#try: '+L except: print '#except: '+L print '-OK.' return L >>> import try2 >>> try2.try2() abc #try: abc 'abc\012' >>> try2.try2() ^C #except: -OK. '\012' >>> try2.try2() aaaaaaa^Cbbbbbbb #except: bbbbbbb -OK. 'bbbbbbb\012' >>> Of the top of my head, I would have expected "aaaaaaa" ( or nothing ) rather than "bbbbbbb" . But I expect that is is defined as "undefined" ? :-) -Steve Majewski (804-982-0831) <sdm7g@Virginia.EDU> -Univ. of Virginia Department of Molecular Physiology and Biological Physics Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA14435 (5.65b/3.8/CWI-Amsterdam); Thu, 15 Apr 1993 01:02:32 +0200 Received: by voorn.cwi.nl with SMTP id AA27854 (5.65b/3.8/CWI-Amsterdam); Thu, 15 Apr 1993 01:02:30 +0200 Message-Id: <9304142302.AA27854=guido@voorn.cwi.nl> To: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Cc: Jaap Vermeulen <jaap@sequent.com>, python-list@cwi.nl Subject: Re: Output disappears when using interrupt key In-Reply-To: Your message of "Wed, 14 Apr 1993 14:59:21 MDT." <199304141859.AA73944@elvis.med.Virginia.EDU> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Thu, 15 Apr 1993 01:02:30 +0200 Sender: Guido.van.Rossum@cwi.nl I tried Steven's try() on two machines and the results differ. On an SGI (System V, though with lots of BSD extensions) the ^C triggers the except clause right away (as it should). On a Sparc running SunOS 4.1 (BSD-based) I need a return after the ^C and entering 'xxx^Cyyy\n' does indeed place 'yyy\n' in the string. That is -- it does this most of the time. Sometimes the initial string remains in the variable L! Knowing more about Python than most of you :-) I can try to explain what's going on. Interrupts in Python are handled by a signal handler which sets a global flag and returns. The interpreter looks at this flag every ten pseudo-instructions or so. Checking it more often is expensive since the interface is a function call, to support the Mac and DOS versions of the interrupt handling interface which works quite differently. This functional interface is also used by other parts of Python that expect interrupts. On System V-like systems, the signal handler causes the read() system call that's buried deep inside stdio to return with an error (EINTR is set), causing the stdio getc() call in Python (in "fileobject.c", getline()) to return EOF, after which getline() checks for an interrupt and reports an error -- the sys.stdin.readline() call never returns successful. However, on BSD-like systems, by default the read() call is *restarted* after a signal handler returns normally (as is any other system call that falls victim of a signal handler). As a side effect the system has emptied its input buffer (which hasn't been transferred to stdio yet because it's waiting for a whole line to be entered). The read() call then proceeds normally so if you entered 'xxx^Cyyy\n' the 'xxx' is thrown away but the 'yyy\n' part is read normally. But the story isn't finished yet: since the interrupt handler *has* been called, the global flag is waiting to be checked by the interpreter's main loop. Depending on where exactly it is it may first assign the result of sys.stdin.readline() to L or first discover that an interrupt has occurred -- which explains why I sometimes see L's initial value. I suspect that AIX 3.2's signal model is based more on BSD than on System V (assuming Steven tried this on AIX -- he only said which system he used for the first try). I can't reproduce Jaap's problem (nor can Steven), so I suspect that it is specific to his system. When an interrupt occurs UNIX discards any output that has been written by the application but not yet transferred to the terminal. Maybe Jaap's system is doing this asynchronously and mistaking output written just after the interrupt for output written just before (I don't know enough about tty drivers to know if this is a reasonable assumption). A solution? Maybe I should just check for an interrupt after *every* read, not just when getc() returns EOF. This would be somewhat expensive (an extra function call for *every* readline() and read() call), but it could be made less expensive by doing it only for tty devices (adding a field to the internal file structure containing the outcome of isatty()). Hoping this sheds enough light, --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Thu, 15 Apr 1993 11:16:47 +0200 Replied: "python-list@cwi.nl " To: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> cc: Jaap Vermeulen <jaap@sequent.com>, python-list@cwi.nl Subject: Re: Output disappears when using interrupt key In-reply-to: Your message of "Wed, 14 Apr 1993 14:59:21 MDT." <199304141859.AA73944@elvis.med.Virginia.EDU> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Thu, 15 Apr 1993 01:02:30 +0200 Sender: guido I tried Steven's try() on two machines and the results differ. On an SGI (System V, though with lots of BSD extensions) the ^C triggers the except clause right away (as it should). On a Sparc running SunOS 4.1 (BSD-based) I need a return after the ^C and entering 'xxx^Cyyy\n' does indeed place 'yyy\n' in the string. That is -- it does this most of the time. Sometimes the initial string remains in the variable L! Knowing more about Python than most of you :-) I can try to explain what's going on. Interrupts in Python are handled by a signal handler which sets a global flag and returns. The interpreter looks at this flag every ten pseudo-instructions or so. Checking it more often is expensive since the interface is a function call, to support the Mac and DOS versions of the interrupt handling interface which works quite differently. This functional interface is also used by other parts of Python that expect interrupts. On System V-like systems, the signal handler causes the read() system call that's buried deep inside stdio to return with an error (EINTR is set), causing the stdio getc() call in Python (in "fileobject.c", getline()) to return EOF, after which getline() checks for an interrupt and reports an error -- the sys.stdin.readline() call never returns successful. However, on BSD-like systems, by default the read() call is *restarted* after a signal handler returns normally (as is any other system call that falls victim of a signal handler). As a side effect the system has emptied its input buffer (which hasn't been transferred to stdio yet because it's waiting for a whole line to be entered). The read() call then proceeds normally so if you entered 'xxx^Cyyy\n' the 'xxx' is thrown away but the 'yyy\n' part is read normally. But the story isn't finished yet: since the interrupt handler *has* been called, the global flag is waiting to be checked by the interpreter's main loop. Depending on where exactly it is it may first assign the result of sys.stdin.readline() to L or first discover that an interrupt has occurred -- which explains why I sometimes see L's initial value. I suspect that AIX 3.2's signal model is based more on BSD than on System V (assuming Steven tried this on AIX -- he only said which system he used for the first try). I can't reproduce Jaap's problem (nor can Steven), so I suspect that it is specific to his system. When an interrupt occurs UNIX discards any output that has been written by the application but not yet transferred to the terminal. Maybe Jaap's system is doing this asynchronously and mistaking output written just after the interrupt for output written just before (I don't know enough about tty drivers to know if this is a reasonable assumption). A solution? Maybe I should just check for an interrupt after *every* read, not just when getc() returns EOF. This would be somewhat expensive (an extra function call for *every* readline() and read() call), but it could be made less expensive by doing it only for tty devices (adding a field to the internal file structure containing the outcome of isatty()). Hoping this sheds enough light, --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA21178 (5.65b/3.8/CWI-Amsterdam); Thu, 15 Apr 1993 03:15:26 +0200 Received: from eng2.sequent.com by gateway.sequent.com (5.61/1.34) id AA07110; Wed, 14 Apr 93 18:16:01 -0700 Received: by eng2.sequent.com (5.65/1.34) id AA25668; Wed, 14 Apr 93 18:15:19 -0700 Message-Id: <9304150115.AA25668@eng2.sequent.com> To: Guido.van.Rossum@cwi.nl Cc: sdm7g@elvis.med.virginia.edu, python-list@cwi.nl Subject: Re: Output disappears when using interrupt key Priority: Normal Precedence: first-class Organization: Sequent Computer Systems, Inc. Service Technology - MailStop: WIL2-610 15450 S.W. Koll Parkway Beaverton, OR 97006-6063 X-Phone: (503) 578-4404 X-Fax: (503) 578-4540 X-Uucp: ...!uunet!sequent!jaap X-Internet: jaap@sequent.com X-Face: C4Cnai$>Eja5I6Vq?(gdN#SXX#`-XgAnmUn&e54sx7@1>q@vkrd_XnH![P>w.:7IJJ;{Bts WJd)u&G!V}0OR?2o5cUgIY}.T{g]PMC=*~]3n_t)S-ZkC(WG}3:#hcA6Oazx:}yc&k,hsF7D},7x>l nyfRjO7$@]fHBN>aC9-M3pKfbYHiy!PWD{_bx~fo})b4tU.;Ao%x[upCI, In-Reply-To: Guido.van.Rossum@cwi.nl's message of Thu, 15 Apr 1993 01:02:30 +0200. <9304142302.AA27854=guido@voorn.cwi.nl> Date: Wed, 14 Apr 1993 18:15:18 -0700 From: Jaap Vermeulen <jaap@sequent.com> | I can't reproduce Jaap's problem (nor can Steven), so I suspect that | it is specific to his system. When an interrupt occurs UNIX discards | any output that has been written by the application but not yet | transferred to the terminal. Maybe Jaap's system is doing this | asynchronously and mistaking output written just after the interrupt | for output written just before (I don't know enough about tty drivers | to know if this is a reasonable assumption). Well, suspicions confirmed! It's a bug in the TCP/IP software w.r.t. telnet sessions (that has been fixed in a later release). I started using rlogin and everything is hunky-dory. Thanks for the help, -Jaap- -- Jaap Vermeulen +--------------------------+ | Sequent Computer Systems | Internet : jaap@sequent.com | Beaverton, Oregon | Uucp : ...uunet!sequent!jaap +--------------------------+ Replied: Thu, 15 Apr 1993 10:08:46 +0200 Replied: "hzsbg01!jbuhrma@hvgtw.att.com " Received: from att-out.att.com by charon.cwi.nl with SMTP id AA00307 (5.65b/3.8/CWI-Amsterdam); Thu, 15 Apr 1993 09:30:21 +0200 From: hzsbg01!jbuhrma@hvgtw.att.com Received: from hzsbc03 by hzsbg01 (4.1/SMI-4.1) id AA01152; Thu, 15 Apr 93 09:24:54 +0200 Date: Thu, 15 Apr 93 09:24:54 +0200 Original-From: hzsbg01!jbuhrma Message-Id: <9304150724.AA01152@hzsbg01> To: Guido.van.Rossum@cwi.nl Subject: Re: Output disappears when using interrupt key > On an SGI (System V, though with lots of BSD extensions) the ^C > triggers the except clause right away (as it should). ^^^^^^^^^^^^ > [...] On System V-like systems, the signal handler causes the read() > system call that's buried deep inside stdio to return with an error > (EINTR is set), causing the stdio getc() call in Python (in > "fileobject.c", getline()) to return EOF, after which getline() checks > for an interrupt and reports an error -- the sys.stdin.readline() call > never returns successful. > However, on BSD-like systems, by default the read() call is > *restarted* after a signal handler returns normally > [...] A solution? Maybe I should just check for an interrupt after > *every* read, not just when getc() returns EOF. This would be > somewhat expensive (an extra function call for *every* readline() and > read() call), but it could be made less expensive by doing it only for > tty devices (adding a field to the internal file structure containing > the outcome of isatty()). Another possibility: Let BSD-like system calls react on interrupts the same way as is done on System V based systems. You probably already know this, but the read(2) man page for SunOS 4.1.3 suggests that this is possible: If the process calling read() or readv() receives a signal before any data are read, the system call is restarted unless the process explicitly set the signal to interrupt the call using sigvec() or sigaction() (see the discussions of SV_INTERRUPT on sigvec(2) and SA_INTERRUPT on sigaction(3V)). If read() or readv() is interrupted by a signal after successfully reading some data, it returns the number of bytes read. Regards, -- Jan-Hein Buhrman -- AT&T Huizen NL -- <jbuhrma%hzsbg01@hvlpa.att.com> -- ---------------------- +31 35 87.4278 --- ...!att!hvlpa!hzsbg01!jbuhrma --- ``Relax..., you're quite safe here'' --- Lady on Art of Noise's Paranoimia To: hzsbg01!jbuhrma@hvgtw.att.com Subject: Re: Output disappears when using interrupt key In-reply-to: Your message of "Thu, 15 Apr 1993 09:24:54 MDT." <9304150724.AA01152@hzsbg01> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Thu, 15 Apr 1993 10:08:46 +0200 Sender: guido >Another possibility: Let BSD-like system calls react on interrupts the >same way as is done on System V based systems. You probably already >know this, but the read(2) man page for SunOS 4.1.3 suggests that this >is possible: [...] Zijn er niet verschillende BSD varianten in de handel die dit anders doen? Ik dacht dat in elk geval "oud" BSD (ik weet niet hoe oud -- 4.1 of 4.2) een andere interface had... Maar ik zal er eens naar kijken... (Had je bewust alleen naar mij gereplied?) --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Thu, 15 Apr 1993 11:11:15 +0200 Replied: "hzsbg01!jbuhrma@hvgtw.att.com " Received: from att-out.att.com by charon.cwi.nl with SMTP id AA02865 (5.65b/3.8/CWI-Amsterdam); Thu, 15 Apr 1993 10:35:20 +0200 From: hzsbg01!jbuhrma@hvgtw.att.com Received: from hzsbc03 by hzsbg01 (4.1/SMI-4.1) id AA08314; Thu, 15 Apr 93 10:30:12 +0200 Date: Thu, 15 Apr 93 10:30:12 +0200 Original-From: hzsbg01!jbuhrma Message-Id: <9304150830.AA08314@hzsbg01> To: Guido.van.Rossum@cwi.nl Subject: Re: Output disappears when using interrupt key > >Another possibility: Let BSD-like system calls react on interrupts the > >same way as is done on System V based systems. You probably already > >know this, but the read(2) man page for SunOS 4.1.3 suggests that this > >is possible: > [...] > > Zijn er niet verschillende BSD varianten in de handel die dit anders > doen? Ik dacht dat in elk geval "oud" BSD (ik weet niet hoe oud -- > 4.1 of 4.2) een andere interface had... Maar ik zal er eens naar > kijken... Vast wel. Dit is waarschijnlijk iets van de laatste BSD release(s). Vroeger had je misschien nog wel een andere truuk, waarbij the read versie die interruptable was een andere naam had en via een #define naar `read' werd gemapt (maar misschien ben ik nu wel in de war met non-blocking read versies die op die manier gemapt werden voor getruukte multiple-thread libs, zonder LWP support in de kernel). Kortom: ik weet het niet! > (Had je bewust alleen naar mij gereplied?) Ja, bescheiden van aard :-). Ik weet dat je het forward-t als je het van algemeen belang acht. -- Jan-Hein Buhrman -- AT&T Huizen NL -- <jbuhrma%hzsbg01@hvlpa.att.com> -- ---------------------- +31 35 87.4278 --- ...!att!hvlpa!hzsbg01!jbuhrma --- There is a severe danger that we might finish the program today To: hzsbg01!jbuhrma@hvgtw.att.com Subject: Re: Output disappears when using interrupt key In-reply-to: Your message of "Thu, 15 Apr 1993 10:30:12 MDT." <9304150830.AA08314@hzsbg01> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Thu, 15 Apr 1993 11:11:15 +0200 Sender: guido Sjoerd deed me een andere truc aan de hand: #ifdef SV_INTERRUPT siginterrupt(SIGINT, 1); #endif I'll summarize to the list, as they say... Doei! --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA04572 (5.65b/3.8/CWI-Amsterdam); Thu, 15 Apr 1993 11:16:52 +0200 Received: by voorn.cwi.nl with SMTP id AA29078 (5.65b/3.8/CWI-Amsterdam); Thu, 15 Apr 1993 11:16:47 +0200 Message-Id: <9304150916.AA29078=guido@voorn.cwi.nl> To: python-list@cwi.nl Subject: Re: Output disappears when using interrupt key In-Reply-To: Your message of "Thu, 15 Apr 1993 01:02:30 MDT." From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Thu, 15 Apr 1993 11:16:47 +0200 Sender: Guido.van.Rossum@cwi.nl In response to Steven's problem of ^C requiring a newline, some people suggested that BSD has a way to turn off system call restarting. The following fix works on our version of SunOS (4.1.1); please try it if you have this problem and see if it compiles and works. (The symbol SV_INTERRUPT is defined in <sys/signal.h> or <signal.h>.) ------------------------------------------------------------------------------- diff -c -r2.8 intrcheck.c *** 2.8 1993/03/29 10:41:47 --- intrcheck.c 1993/04/15 08:58:58 *************** *** 140,145 **** --- 140,154 ---- { if (signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, intcatcher); + #ifdef SV_INTERRUPT + /* This is for SunOS and other modern BSD derivatives. + It means that system calls (like read()) are not restarted + after an interrupt. This is necessary so interrupting a + read() or readline() call works as expected. + XXX On old BSD (pure 4.2 or older) you may have to do this + differently! */ + siginterrupt(SIGINT, 1); + #endif } int ------------------------------------------------------------------------------- Thankyou Jan-Hein Buhrman and Sjoerd Mullender, --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from guppie.cwi.nl by charon.cwi.nl with SMTP id AA18052 (5.65b/3.8/CWI-Amsterdam); Mon, 10 May 1993 19:49:25 +0200 Received: by guppie.cwi.nl with SMTP id AA04778 (5.65b/3.8/CWI-Amsterdam); Mon, 10 May 1993 17:49:24 GMT Message-Id: <9305101749.AA04778=guido@guppie.cwi.nl> To: Jaap Vermeulen <jaap@sequent.com> Cc: python-list@cwi.nl Subject: Re: SystemExit In-Reply-To: Your message of "Mon, 10 May 1993 10:38:45 MDT." <9305101738.AA23653@eng2.sequent.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Mon, 10 May 1993 17:49:24 +0200 Sender: Guido.van.Rossum@cwi.nl On the contrary, SystemExit is a big improvement. Now you can do things like "put the tty in raw mode" try: "some code that may call sys.exit(n) somewhere deep inside" finally: "put the tty in cooked mode again" without having to worry about the possibility that you never hit the finally clause. It is still possible but less likely during normal code. Nobody in their right mind would use posix._exit(n) except to exit from a forked child, but lots of code may call sys.exit(n) -- as you have experienced, otherwise you wouldn't have started this thread in the first place :-) Code that uses an unqualified except clause is always suspect. It may mask exceptions caused deep inside that you didn't know were possible, such as SystemError, MemoryError or TypeError in code that you thought had no bugs. A solution to your problem that is more elegant than testing the value of sys.exc_type (which is really meant for the debugger only), and which generalizes slightly better as well, is the following: try: "some code that may raise any exception" except SystemExit, status: raise SystemExit, status except: "handle any other kind of error" --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> PS: I'll reply to your previous mail later since the issues are more complicated... Replied: Mon, 10 May 1993 18:11:22 +0200 Replied: "Lance Ellinghouse <lance@markv.com> " Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA14984 (5.65b/3.8/CWI-Amsterdam); Mon, 10 May 1993 18:02:02 +0200 Received: by hermix.markv.com id aa02307; 10 May 93 8:59 PDT From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: hegt@lebe.iaci.kun.nl Subject: Re: python/stdwin/motif Cc: python-list@cwi.nl Date: Mon, 10 May 93 8:50:25 PDT Message-Id: <9305100850.aa01768@hermix.markv.com> > Guido told me, that he is thinking about going to support Motif as the > underlying window system of Python rather than his own STDWIN. This is very good news! > I can think of some reasons why this is a good idea, but also why I > would personally not make this choice: > > - as far as I can see there is not much support for Motif other than as > a widget set on top of X11 Incorrect. Almost every PC X-windows package supports Motif, almost every UNIX platforms supports Motif, Even Mac-X supports Motif.. Remember, once the application is compiled and linked with Motif libraries, the Widget set is INDEPENDENT of the supplied X-windows system since everything folds down to Xlib. The server does not have to have Motif on it at all.. > - although X11 is available on several platforms, not all of them > include Motif, that is for a reasonable price; practically speaking, > I think that this means the end of window-based development using > Python on non-unix systems Motif is going into the public domain. It will no longer be owned by OSF in the very near future. it will be similar to X then. You will be able to FTP and grab the Motif sources (Don't ask me the source of my info). > - what is the purpose a of window-system binding for Python and wouldn't > we rather have some portable Xlib level kind of window functionality > on all the obvious platforms (mac/pc/unix-x11); we could think of the > XVT type of solution, which is more or less an extension of the > thoughts behind STDWIN, but developed from the other end, i.e. from > existing window systems Motif is more standard then STDWIN. People like the look and feel of Motif. The first time I ran a STDWIN program, I thought it looked like a toy. Put a nice Motif look to it and it can become a product. > I think that the underlying question is: who is using Python and for > what? As a newcomer to Python and this list I have no idea about that. > My own main interest is cross-platform non-standard (so: not MS-Win, > Motif, OpenLook etc.) GUI prototyping. ^^^^^^^^ OpenLook is dead. Sun is dropping it completely. I know that I will very much enjoy the Motif interface for Python! I am creating a commercial product based on Python and the STDWIN interface does not look professional enough. There is no need to discontinue to use STDWIN for those that need it, but I for one need Motif. Lance Ellinghouse lance@markv.com Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA15387 (5.65b/3.8/CWI-Amsterdam); Mon, 10 May 1993 18:12:30 +0200 Received: by voorn.cwi.nl with SMTP id AA28879 (5.65b/3.8/CWI-Amsterdam); Mon, 10 May 1993 18:12:29 +0200 Message-Id: <9305101612.AA28879=guido@voorn.cwi.nl> To: python-list@cwi.nl Subject: Re: python/stdwin/motif Date: Mon, 10 May 1993 18:12:28 +0200 From: Guido van Rossum <Guido.van.Rossum@cwi.nl> [">" is Lance Ellinghouse, "> >" is Rob Hegt:] > > I can think of some reasons why this is a good idea, but also why I > > would personally not make this choice: > > > > - as far as I can see there is not much support for Motif other than as > > a widget set on top of X11 > > Incorrect. Almost every PC X-windows package supports Motif, almost every > UNIX platforms supports Motif, Even Mac-X supports Motif.. Remember, > once the application is compiled and linked with Motif libraries, > the Widget set is INDEPENDENT of the supplied X-windows system since > everything folds down to Xlib. The server does not have to have > Motif on it at all.. Hmm, are you implying that there are PC X-windows packages that allow *clients* to run under DOS or Windows? All I know if in this area are packages that are usable as an X server, allowing you to run X clients remotely on a UNIX machine with their windows on your PC. But what Rob is worried about is that he won't be able to write portable *clients* -- if they use Motif they will have to run an a UNIX box. Or have I missed something? (Quite possible, I don't follow all the X-related market news any more...) > Motif is more standard then STDWIN. People like the look and feel of > Motif. The first time I ran a STDWIN program, I thought it looked > like a toy. Put a nice Motif look to it and it can become a product. One thing I'm thinking of is to create a STDWIN port that uses Motif instead of bare Xlib underneath. It may even be possible to do this entirely in Python, once my Motif/Xt port has sufficient Xlib functionality (currently it has none). This would help Rob as well: he can continue to use STDWIN for "toy" apps on his Mac or PC, but on UNIX boxes his apps will follow the Motif style. (To make one thing clear: I don't really plan to discontinue STDWIN, but I don't want to make additions to it either, sice the audience is really too small. Had there been a Windows port two years ago, the situation might have been different... Sigh.) --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA16179 (5.65b/3.8/CWI-Amsterdam); Mon, 10 May 1993 18:39:09 +0200 From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: Guido.van.Rossum@cwi.nl Subject: Re: python/stdwin/motif Cc: python-list@cwi.nl Date: Mon, 10 May 93 9:35:45 PDT Message-Id: <9305100935.aa05771@hermix.markv.com> ["> " is Guido, "> >" is Lance Ellinghouse, "> > >" is Rob Hegt:] > > > > I can think of some reasons why this is a good idea, but also why I > > > would personally not make this choice: > > > > > > - as far as I can see there is not much support for Motif other than as > > > a widget set on top of X11 > > > > Incorrect. Almost every PC X-windows package supports Motif, almost every > > UNIX platforms supports Motif, Even Mac-X supports Motif.. Remember, > > once the application is compiled and linked with Motif libraries, > > the Widget set is INDEPENDENT of the supplied X-windows system since > > everything folds down to Xlib. The server does not have to have > > Motif on it at all.. > > Hmm, are you implying that there are PC X-windows packages that allow > *clients* to run under DOS or Windows? All I know if in this area are > packages that are usable as an X server, allowing you to run X clients > remotely on a UNIX machine with their windows on your PC. But what > Rob is worried about is that he won't be able to write portable > *clients* -- if they use Motif they will have to run an a UNIX box. > Or have I missed something? (Quite possible, I don't follow all the > X-related market news any more...) DeskView/X allows you to compile X *CLIENTS* under DOS that talk X. They have Motif libraries also. There are also a couple others that i have heard about but their names don't jump out at me (since I don't deal with DOS at all..). > > Motif is more standard then STDWIN. People like the look and feel of > > Motif. The first time I ran a STDWIN program, I thought it looked > > like a toy. Put a nice Motif look to it and it can become a product. > > One thing I'm thinking of is to create a STDWIN port that uses Motif > instead of bare Xlib underneath. It may even be possible to do this > entirely in Python, once my Motif/Xt port has sufficient Xlib > functionality (currently it has none). This would help Rob as well: > he can continue to use STDWIN for "toy" apps on his Mac or PC, but on > UNIX boxes his apps will follow the Motif style. > > (To make one thing clear: I don't really plan to discontinue STDWIN, > but I don't want to make additions to it either, sice the audience is > really too small. Had there been a Windows port two years ago, the > situation might have been different... Sigh.) This is the way that I see things.. STDWIN is still there and people can make inprovements as people need... MotifWIN comes into being and people make improvements as people need. Both have their uses. People programming in Python can choose which to program against by "import"'ing the one they want. There is no need for one to REPLACE the other. Lance Ellinghouse lance@markv.com Received: from srv01s4.cas.org by charon.cwi.nl with SMTP id AA16791 (5.65b/3.8/CWI-Amsterdam); Mon, 10 May 1993 19:02:07 +0200 Date: Mon, 10 May 93 13:01:59 EDT From: jcv26@cas.org (Jon Vander Hill) Message-Id: <9305101701.AA02842@cas.org> To: Lance Ellinghouse <lance@markv.com> Cc: python-list@cwi.nl Subject: Re: python/stdwin/motif In-Reply-To: <9305100850.aa01768@hermix.markv.com> References: <9305100850.aa01768@hermix.markv.com> >>>>> On Mon, 10 May 93 8:50:25 PDT, Lance Ellinghouse <lance@markv.com> said: > Incorrect. Almost every PC X-windows package supports Motif, almost every > UNIX platforms supports Motif, Even Mac-X supports Motif.. Remember, > once the application is compiled and linked with Motif libraries, > the Widget set is INDEPENDENT of the supplied X-windows system since > everything folds down to Xlib. The server does not have to have > Motif on it at all.. Anyone running Motif applications on under Sun's OpenWindows can attest to that! SunOS is the only UNIX I know of that doesn't ship with a Motif library (although I heard they were handing one out at a recent developers conference). Sun is supposed to have a Motif library in Solaris 2.2. > Motif is going into the public domain. It will no longer be owned by OSF > in the very near future. it will be similar to X then. You will > be able to FTP and grab the Motif sources (Don't ask me the source > of my info). Okay I won't ask (but I'm intensely curious). Can you provide a time frame? Personally, I think this must happen for UNIX vendors to survive the NT juggernaut. >> I think that the underlying question is: who is using Python and for >> what? As a newcomer to Python and this list I have no idea about that. >> My own main interest is cross-platform non-standard (so: not MS-Win, >> Motif, OpenLook etc.) GUI prototyping. > ^^^^^^^^ OpenLook is dead. Sun is dropping it completely. As I understand it, Sun is moving toward an interoperability standard (along with basically any UNIX vendor who doesn't want to get blown away by NT) of which Motif is a part. How much of this is mere corporate posturing is anyone's guess given that Windows NT is still not a product. I give OpenLook about two more years as support gradually diminishes. Overall, I think Motif and Python would be good for eachother. Jon Vander Hill jon@cas.org Replied: Mon, 10 May 1993 21:17:07 +0200 Replied: "Jaap Vermeulen <jaap@sequent.com> python-list" Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA17345 (5.65b/3.8/CWI-Amsterdam); Mon, 10 May 1993 19:24:09 +0200 Received: from eng2.sequent.com by gateway.sequent.com (5.61/1.34) id AA02251; Mon, 10 May 93 10:24:10 -0700 Received: by eng2.sequent.com (5.65/1.34) id AA21460; Mon, 10 May 93 10:24:00 -0700 Message-Id: <9305101724.AA21460@eng2.sequent.com> To: python-list@cwi.nl Subject: Some suggestion for python classes Priority: Normal Precedence: first-class Organization: Sequent Computer Systems, Inc. Service Technology - MailStop: WIL2-610 15450 S.W. Koll Parkway Beaverton, OR 97006-6063 X-Phone: (503) 578-4404 X-Fax: (503) 578-4540 X-Uucp: ...!uunet!sequent!jaap X-Internet: jaap@sequent.com X-Face: C4Cnai$>Eja5I6Vq?(gdN#SXX#`-XgAnmUn&e54sx7@1>q@vkrd_XnH![P>w.:7IJJ;{Bts WJd)u&G!V}0OR?2o5cUgIY}.T{g]PMC=*~]3n_t)S-ZkC(WG}3:#hcA6Oazx:}yc&k,hsF7D},7x>l nyfRjO7$@]fHBN>aC9-M3pKfbYHiy!PWD{_bx~fo})b4tU.;Ao%x[upCI, Date: Mon, 10 May 93 10:23:59 PDT From: Jaap Vermeulen <jaap@sequent.com> Having used the python classes for a bit, I came up with some pieces that would make life a lot easier when using the classes within python. They boil down to 3 suggestions. I used some simple examples. 1) When using a class method, it would be nice if the calling class would be added as the 1st argument of the method. First let me explain the nomenclature. A class method is a method invoked through the class instead of the method. I.e. class foo: def bar(): something Invoking foo.bar() is invoking a class method. You could invoke the same method as a instance method, foo().bar(), however, it would result in a 'TypeError: arg cound mismatch' since the instance itself is automatically prepended to the argument list. What I propose is to do the same when you invoke the method as a class method, and prepend the class to the method. This would result in: class foo: def bar(self): print type(self) Invoking foo.bar() would result in <type 'class'>, invoking foo().bar() would result in <type 'instance'>. It is up to the programmer to correctly code, invoke and identify class method vs. instance methods (as with a lot of other things in python). The benefit would be that you can define a class method in a base class, and still have access to the invoking class. i.e. class foo: def new(self): new_instance = self() ... return new_instance class bar(foo): ... Invoking bar.new() would return an instance of bar. The current work-around is to invoke the class method as bar.new(bar). 2) It would be nice to have a special operator to implement the 'super' functionality. This functionality allows you to start searching for a method starting at the base classes, not the current class. The current workaround is to define a function to delete the method from the current class (if it's there), retrieve it using the normal method, and replacing the method in the current class. This allows you to write: class bar(foo): def new(self): new_instance = super(self, 'new')(self) ... return new_instance What I would like to see is some special operator that does this for you, e.g. using a carrot: new_instance = self^new() 3) It would be nice to be able to retrieve the name of a class. The attribute exists, but is empty. I.e. bar.__name__ returns None. Also, the address operator Guido was talking about would come in very handy, since you would be able to define something like this (given that '&' is the address operator): class bar(foo): def __repr__(self): try: return '<class ' + self.__name__ + 'at ' + `&self` except: return '<instance ' + self.__class__.__name__ + 'at ' + `&self` This brings up another point, and that is that __repr__ currently doesn't work for classes, it would be nice if it did. Suggestions and comments are welcome. -Jaap- -- Jaap Vermeulen +--------------------------+ | Sequent Computer Systems | Internet : jaap@sequent.com | Beaverton, Oregon | Uucp : ...uunet!sequent!jaap +--------------------------+ Replied: Mon, 10 May 1993 17:49:23 +0200 Replied: "Jaap Vermeulen <jaap@sequent.com> python-list" Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA17663 (5.65b/3.8/CWI-Amsterdam); Mon, 10 May 1993 19:38:52 +0200 Received: from eng2.sequent.com by gateway.sequent.com (5.61/1.34) id AA02737; Mon, 10 May 93 10:38:55 -0700 Received: by eng2.sequent.com (5.65/1.34) id AA23653; Mon, 10 May 93 10:38:46 -0700 Message-Id: <9305101738.AA23653@eng2.sequent.com> To: python-list@cwi.nl Subject: SystemExit Priority: Normal Precedence: first-class Organization: Sequent Computer Systems, Inc. Service Technology - MailStop: WIL2-610 15450 S.W. Koll Parkway Beaverton, OR 97006-6063 X-Phone: (503) 578-4404 X-Fax: (503) 578-4540 X-Uucp: ...!uunet!sequent!jaap X-Internet: jaap@sequent.com X-Face: C4Cnai$>Eja5I6Vq?(gdN#SXX#`-XgAnmUn&e54sx7@1>q@vkrd_XnH![P>w.:7IJJ;{Bts WJd)u&G!V}0OR?2o5cUgIY}.T{g]PMC=*~]3n_t)S-ZkC(WG}3:#hcA6Oazx:}yc&k,hsF7D},7x>l nyfRjO7$@]fHBN>aC9-M3pKfbYHiy!PWD{_bx~fo})b4tU.;Ao%x[upCI, Date: Mon, 10 May 1993 10:38:45 -0700 From: Jaap Vermeulen <jaap@sequent.com> I have some gripes about the SystemExit. Firstly all the code that used to work, such as: try: some code that includes an sys.exit() deep down except: something else doesn't work any more since it's entering the except. What I want is catching all possible scenarios *except* system exit. Yes I could use posix._exit(), but that doesn't flush things properly etc. Now I'm forced to write: try: some code that includes and sys.exit() deep down except: if sys.exc_type == SystemExit: sys.exit() something else for every such contruct. Furthermore, if I were to use the posix._exit() function, I can't on DOS since it doesn't exist. As a matter of fact I had to clean up the os.py module to work properly by changing the line: try: from posix import * from posix import _exit name = 'posix' ... to: try: from posix import * try: from posix import _exit except: pass name = 'posix' ... I know that I'm the one that was asking for a cleanup function, which Guido dutifully implemented, but I didn't ask for an exception if I just want to exit. Except for the solutions outlined above, does somebody else come up with a convenient solution? Looks like backwards compatibility is slightly broken here. And I don't really see the rational for this change, since I could have raised the exception myself if I needed it. Thanks, -Jaap- -- Jaap Vermeulen +--------------------------+ | Sequent Computer Systems | Internet : jaap@sequent.com | Beaverton, Oregon | Uucp : ...uunet!sequent!jaap +--------------------------+ Replied: Mon, 10 May 1993 20:48:42 +0200 Replied: "Jaap Vermeulen <jaap@sequent.com> python-list@cwi.nl" Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA18821 (5.65b/3.8/CWI-Amsterdam); Mon, 10 May 1993 20:11:25 +0200 Received: from eng2.sequent.com by gateway.sequent.com (5.61/1.34) id AA04472; Mon, 10 May 93 11:11:26 -0700 Received: by eng2.sequent.com (5.65/1.34) id AA29028; Mon, 10 May 93 11:11:15 -0700 Message-Id: <9305101811.AA29028@eng2.sequent.com> To: Guido.van.Rossum@cwi.nl Cc: python-list@cwi.nl Subject: Re: SystemExit Priority: Normal Precedence: first-class Organization: Sequent Computer Systems, Inc. Service Technology - MailStop: WIL2-610 15450 S.W. Koll Parkway Beaverton, OR 97006-6063 X-Phone: (503) 578-4404 X-Fax: (503) 578-4540 X-Uucp: ...!uunet!sequent!jaap X-Internet: jaap@sequent.com X-Face: C4Cnai$>Eja5I6Vq?(gdN#SXX#`-XgAnmUn&e54sx7@1>q@vkrd_XnH![P>w.:7IJJ;{Bts WJd)u&G!V}0OR?2o5cUgIY}.T{g]PMC=*~]3n_t)S-ZkC(WG}3:#hcA6Oazx:}yc&k,hsF7D},7x>l nyfRjO7$@]fHBN>aC9-M3pKfbYHiy!PWD{_bx~fo})b4tU.;Ao%x[upCI, In-Reply-To: Guido.van.Rossum@cwi.nl's message of Mon, 10 May 1993 17:49:24 +0200. <9305101749.AA04778=guido@guppie.cwi.nl> Date: Mon, 10 May 1993 11:11:14 -0700 From: Jaap Vermeulen <jaap@sequent.com> | without having to worry about the possibility that you never hit the | finally clause. It is still possible but less likely during normal I though you would *always* hit the finally clause, even if you use sys.exit()? (I mean: wasn't this true for the previous version too?) | code. Nobody in their right mind would use posix._exit(n) except to | exit from a forked child, but lots of code may call sys.exit(n) -- as True, still, os.py is broken on DOS. | Code that uses an unqualified except clause is always suspect. It may | mask exceptions caused deep inside that you didn't know were possible, | such as SystemError, MemoryError or TypeError in code that you thought | had no bugs. Yes, I know. Listing all exceptions I want to catch in separate lines, yet all of them using the same code, is a hassle (especially if there are quite a few of them). Couldn't we add something that would allow you to pass a list of exception types as the first argument to except:? Also, the whole stacktrace is a hassle. It is great for the developer, but confusing for the ordinary user that doesn't care for it (espacially if the python program is a subprogram of another program). That's why often I wrap the whole program in a try: except:, forgoing the stacktrace, but printing the problem (using the exc_type and exc_value). | try: | "some code that may raise any exception" | except SystemExit, status: | raise SystemExit, status | except: | "handle any other kind of error" Forgot about that one. :-) Thanks, -Jaap- -- Jaap Vermeulen +--------------------------+ | Sequent Computer Systems | Internet : jaap@sequent.com | Beaverton, Oregon | Uucp : ...uunet!sequent!jaap +--------------------------+ To: Jaap Vermeulen <jaap@sequent.com> cc: python-list@cwi.nl Subject: Re: SystemExit In-reply-to: Your message of "Mon, 10 May 1993 11:11:14 MDT." <9305101811.AA29028@eng2.sequent.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Mon, 10 May 1993 20:48:44 +0200 Sender: guido > | without having to worry about the possibility that you never hit the > | finally clause. It is still possible but less likely during normal > > I though you would *always* hit the finally clause, even if you use > sys.exit()? (I mean: wasn't this true for the previous version too?) No, originally sys.exit() would just call the C routine exit(). There were complaints about this and I changed it into an exception so that finally clauses would work. (There is no way to execute them except by letting the stack unwind itself.) Also the exception makes it possible for a debugger or similar package to trap sys.exit() without patching up the sys module. > | code. Nobody in their right mind would use posix._exit(n) except to > | exit from a forked child, but lots of code may call sys.exit(n) -- as > > True, still, os.py is broken on DOS. Then fix os.py! (This particular bug will be fixed in the next release.) Note that os.py also assigns sep = '/' which you probably don't want under DOS, although I think it does work; should I fix it? (I think it should also set name = 'dos' or perhaps 'msdos'.) Under DOS the _exit() function shouldn't be in os since it isn't in the C library either. (Or is it? Then maybe I should add it to the DOS version of the posix interface... Please enlighten me, I always thought that _exit() is specific to real UNIX and not specified by Standard C.) > | Code that uses an unqualified except clause is always suspect. It may > | mask exceptions caused deep inside that you didn't know were possible, > | such as SystemError, MemoryError or TypeError in code that you thought > | had no bugs. > > Yes, I know. Listing all exceptions I want to catch in separate lines, > yet all of them using the same code, is a hassle (especially if there > are quite a few of them). Couldn't we add something that would allow > you to pass a list of exception types as the first argument to > except:? You can already do this! (I believe it has always been possible and is even documented in the reference manual.) try: "some code" except (ex1, ex2, ex3), value: "handler for three different exceptions" > Also, the whole stacktrace is a hassle. It is great for the developer, > but confusing for the ordinary user that doesn't care for it > (espacially if the python program is a subprogram of another program). > That's why often I wrap the whole program in a try: except:, forgoing > the stacktrace, but printing the problem (using the exc_type and > exc_value). I would imagine that the vast majority Python scripts are only ever run by their author, so having a stack trace by default makes sense. If your script is bugfree, it should never print a stack trace. If it does generate an exception, the user can show (or mail) the stack trace to the author of the script who can then find the bug. Printing only the exception would make this much harder. I don't understand why you say that the ordinary user doesn't care: the program failed to do what it should, so they have every right to complain! --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA20435 (5.65b/3.8/CWI-Amsterdam); Mon, 10 May 1993 21:17:12 +0200 Received: by voorn.cwi.nl with SMTP id AA29134 (5.65b/3.8/CWI-Amsterdam); Mon, 10 May 1993 21:17:10 +0200 Message-Id: <9305101917.AA29134=guido@voorn.cwi.nl> To: Jaap Vermeulen <jaap@sequent.com> Cc: python-list@cwi.nl Subject: Re: Some suggestion for python classes In-Reply-To: Your message of "Mon, 10 May 1993 10:23:59 MDT." <9305101724.AA21460@eng2.sequent.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Mon, 10 May 1993 21:17:09 +0200 Sender: Guido.van.Rossum@cwi.nl Jaap Vermeulen writes: > 1) When using a class method, it would be nice if the calling class > would be added as the 1st argument of the method. > > First let me explain the nomenclature. A class method is a method > invoked through the class instead of the method. I.e. > > class foo: > def bar(): > something > > Invoking foo.bar() is invoking a class method. You could invoke > the same method as a instance method, foo().bar(), however, it > would result in a 'TypeError: arg cound mismatch' since the > instance itself is automatically prepended to the argument list. > What I propose is to do the same when you invoke the method as a > class method, and prepend the class to the method. This would > result in: > > class foo: > def bar(self): > print type(self) > > Invoking foo.bar() would result in <type 'class'>, invoking > foo().bar() would result in <type 'instance'>. It is up to the > programmer to correctly code, invoke and identify class method vs. > instance methods (as with a lot of other things in python). > > The benefit would be that you can define a class method in a base > class, and still have access to the invoking class. i.e. > > class foo: > def new(self): > new_instance = self() > ... > return new_instance > > class bar(foo): > ... > > Invoking bar.new() would return an instance of bar. The current > work-around is to invoke the class method as bar.new(bar). Ah, but calling a class method is also used in another situation. The standard "idiom" for extending a method is as follows: class Base: def doit(self, how): "do it in a basic way" class Derived(Base): def doit(self, how): "do a little bit in advance" Base.doit(self, how) "do it some more" For the interpreter, the call to Base.doit(self, how) in a method of a Derived instance is indistinguishable from a call somewhere else. This is actually one of the foundations of Python's "cheap" implementation of classes and inheritances, and I would hate to lose it. (The point is that the interpreter has no idea that it is executing a method -- all it ever sees is function calls.) I have a feeling that the only situation where a class method needs to know the class from which it was really called is in situations where you want to create a new class instance without any reference to another. There is already a standard way to do this, and I don't see why "C.new()" is much better than "C().init()" -- the two extra parentheses don't really bother me. If you insist on having a function called new() to create class instances, why not make it a global function and call it with the class as explicit argument, e.g. "new(C)" ? But maybe your example is too simplistic to show what the real problem is. What does your new() function do between creating the new instance and returning it? Can't this be done by the instance's init() function? > 2) It would be nice to have a special operator to implement the > 'super' functionality. This functionality allows you to start > searching for a method starting at the base classes, not the > current class. The current workaround is to define a function to > delete the method from the current class (if it's there), retrieve > it using the normal method, and replacing the method in the current > class. This allows you to write: > > class bar(foo): > def new(self): > new_instance = super(self, 'new')(self) > ... > return new_instance > > What I would like to see is some special operator that does this > for you, e.g. using a carrot: > > new_instance = self^new() See my example above of how to extend a method in Python. The point is that the name of the base class is statically known at the point where you write the code that needs to use it, so there really is no good reason to dynamically look it up -- you might as well use the name of the base class. You don't give an implementation of your super() workaround -- I have a feeling that it might fail if there are several layers of derived classes stacked on top of bar and some of them don't define a new() method. (BTW, I always thought that '^' was called "caret" -- is this a special version with night vision? :-) > 3) It would be nice to be able to retrieve the name of a class. The > attribute exists, but is empty. I.e. bar.__name__ returns None. > Also, the address operator Guido was talking about would come in > very handy, since you would be able to define something like this > (given that '&' is the address operator): > > class bar(foo): > def __repr__(self): > try: return '<class ' + self.__name__ + 'at ' + `&self` > except: > return '<instance ' + self.__class__.__name__ + 'at ' + `&self` Yes, this is a bug. I should fix it. It's difficult to fix because of the way class construction is implemented, but nevertheless I should fix it. BTW, the address-of operator will be called id() and return a plain integer. (Adding unary & would mean a change to the grammar, and that's much too drastic for such a little-used function.) > This brings up another point, and that is that __repr__ currently > doesn't work for classes, it would be nice if it did. I don't understand how you want it to work. Do you mean that a class should be able to decide how it will be printed? How would you use that? How would you distinguish between the __repr__ method for instances and the one for the class? General comments: I have a feeling that you are trying to use classes where you should be using instances; this would also explain a few of your wishes above. But again, maybe I'm missing your point -- please give more realistic examples to show how you are using all this. Your ideas are certainly worth being investigated, it's just that everything fits together so tightly that moving one piece usually requires moving LOTS of other pieces. Sometimes at first you don't see why a piece is necessary, until you take several steps backwards and see the whole structure again... Cheers, --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from lebe.iaci.kun.nl by charon.cwi.nl with SMTP id AA07615 (5.65b/3.8/CWI-Amsterdam); Mon, 10 May 1993 15:08:49 +0200 Received: by lebe.local (5.57/Ultrix3.0-C) id AA05212; Mon, 10 May 93 15:08:22 +0200 Message-Id: <9305101308.AA05212@lebe.local> To: python-list@cwi.nl Subject: python/stdwin/motif From: hegt@lebe.iaci.kun.nl Date: Mon, 10 May 93 15:08:20 CDT Sender: hegt@lebe.local Hello all, Guido told me, that he is thinking about going to support Motif as the underlying window system of Python rather than his own STDWIN. I can think of some reasons why this is a good idea, but also why I would personally not make this choice: - as far as I can see there is not much support for Motif other than as a widget set on top of X11 - although X11 is available on several platforms, not all of them include Motif, that is for a reasonable price; practically speaking, I think that this means the end of window-based development using Python on non-unix systems - what is the purpose a of window-system binding for Python and wouldn't we rather have some portable Xlib level kind of window functionality on all the obvious platforms (mac/pc/unix-x11); we could think of the XVT type of solution, which is more or less an extension of the thoughts behind STDWIN, but developed from the other end, i.e. from existing window systems I think that the underlying question is: who is using Python and for what? As a newcomer to Python and this list I have no idea about that. My own main interest is cross-platform non-standard (so: not MS-Win, Motif, OpenLook etc.) GUI prototyping. Rob Hegt Replied: Tue, 11 May 1993 10:11:43 +0200 Replied: "John DeGood <degood@lf.hp.com> " Received: from hplb.hpl.hp.com by charon.cwi.nl with SMTP id AA22091 (5.65b/3.8/CWI-Amsterdam); Mon, 10 May 1993 22:23:16 +0200 Received: from hpavuu.lf.hp.com by hplb.hpl.hp.com; Mon, 10 May 93 21:16:26 +0100 Received: by hpavun.lf.hp.com (16.8/15.5+IOS 3.22) id AA14101; Mon, 10 May 93 16:24:32 -0400 Date: Mon, 10 May 93 16:24:32 -0400 From: John DeGood <degood@lf.hp.com> Message-Id: <9305102024.AA14101@hpavun.lf.hp.com> To: guido@cwi.nl Subject: Re: python/stdwin/motif Cc: python-list@cwi.nl > DeskView/X allows you to compile X *CLIENTS* under > DOS that talk X. They have Motif libraries also. There are > also a couple others that i have heard about but their names don't > jump out at me (since I don't deal with DOS at all..). Hummingbird Communications, Ltd (Ontario, Canada) has an X software development kit for Microsoft Windows with Xlib, Xt intrinsics, and Xaw and Xmu libraries. They also have an optional OSF/Motif toolkit. With these one can create X Window clients that execute on a PC under Microsoft Windows and can be displayed on the local PC X server or on any remote PC or Unix system running an X server. > One thing I'm thinking of is to create a STDWIN port that uses Motif > instead of bare Xlib underneath. It may even be possible to do this > entirely in Python, once my Motif/Xt port has sufficient Xlib > functionality (currently it has none). This would help Rob as well: > he can continue to use STDWIN for "toy" apps on his Mac or PC, but on > UNIX boxes his apps will follow the Motif style. A port to Motif would give STDWIN on Unix a nice facelift. My unfinished Microsoft Windows port of STDWIN uses the Windows style, which looks similar to Motif. So although the current STDWIN-on-Xlib is an "ugly duckling" the "toy" platforms already look nice. :-) > (To make one thing clear: I don't really plan to discontinue STDWIN, > but I don't want to make additions to it either, sice the audience is > really too small. Had there been a Windows port two years ago, the > situation might have been different... Sigh.) In these past two years several commercial cross-platform GUI libraries have been introduced, but unlike STDWIN they are proprietary and expensive. Even if Motif became "public domain" I don't think it would replace STDWIN because only a tiny fraction of PC and Mac users currently have the necessary X server software. So STDWIN may continue to be a useful tool for Python cross-platform development for some time. John DeGood degood@lf.hp.com Hewlett-Packard Little Falls Site (Wilmington, Delaware) Replied: Tue, 11 May 1993 09:23:54 +0200 Replied: "Jaap Vermeulen <jaap@sequent.com> " Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA22978 (5.65b/3.8/CWI-Amsterdam); Mon, 10 May 1993 22:56:38 +0200 Received: from eng2.sequent.com by gateway.sequent.com (5.61/1.34) id AA10887; Mon, 10 May 93 13:56:39 -0700 Received: by eng2.sequent.com (5.65/1.34) id AA18117; Mon, 10 May 93 13:56:29 -0700 Message-Id: <9305102056.AA18117@eng2.sequent.com> To: Guido.van.Rossum@cwi.nl Subject: Re: SystemExit Priority: Normal Precedence: first-class Organization: Sequent Computer Systems, Inc. Service Technology - MailStop: WIL2-610 15450 S.W. Koll Parkway Beaverton, OR 97006-6063 X-Phone: (503) 578-4404 X-Fax: (503) 578-4540 X-Uucp: ...!uunet!sequent!jaap X-Internet: jaap@sequent.com X-Face: C4Cnai$>Eja5I6Vq?(gdN#SXX#`-XgAnmUn&e54sx7@1>q@vkrd_XnH![P>w.:7IJJ;{Bts WJd)u&G!V}0OR?2o5cUgIY}.T{g]PMC=*~]3n_t)S-ZkC(WG}3:#hcA6Oazx:}yc&k,hsF7D},7x>l nyfRjO7$@]fHBN>aC9-M3pKfbYHiy!PWD{_bx~fo})b4tU.;Ao%x[upCI, In-Reply-To: Guido.van.Rossum@cwi.nl's message of Mon, 10 May 1993 20:48:44 +0200. <9305101848.AA29091=guido@voorn.cwi.nl> Date: Mon, 10 May 1993 13:56:28 -0700 From: Jaap Vermeulen <jaap@sequent.com> I didn't include the list any more since this discussion watered down to crossing every T. | No, originally sys.exit() would just call the C routine exit(). There Ok. issue closed. | Then fix os.py! (This particular bug will be fixed in the next | release.) Yes, I did and gave you my solution. | Note that os.py also assigns sep = '/' which you probably don't want | under DOS, although I think it does work; should I fix it? (I think | it should also set name = 'dos' or perhaps 'msdos'.) Good idea! I'll send you what I come up with. | Under DOS the _exit() function shouldn't be in os since it isn't in | the C library either. (Or is it? Then maybe I should add it to the | DOS version of the posix interface... Please enlighten me, I always | thought that _exit() is specific to real UNIX and not specified by | Standard C.) I'm not saying it should be there (what does posix mean under msdos?). I'm saying that os.py callously tried to include it. | > are quite a few of them). Couldn't we add something that would allow | > you to pass a list of exception types as the first argument to | > except:? | | You can already do this! (I believe it has always been possible and | is even documented in the reference manual.) You're right, I glanced over the syntax, which doesn't make it clear. The next page explains it. Maybe the syntax could be updated? (i.e. from ("except" [condition] ["," target]]... to e.g. ("except" [conditions] ["," target]]...) | If your script is bugfree, it should never print a stack trace. If it | does generate an exception, the user can show (or mail) the stack | trace to the author of the script who can then find the bug. Printing | only the exception would make this much harder. I don't understand I wouldn't care about the stack trace so much if the format wasn't so confusing to the ordinary user (yes, other people than myself are using python programs). Maybe, if the error message could be called out more and the stack trace could be preceded with some disclaimer, it wouldn't be so confusing to the ordinary user. They complain to me: WHAT IS HAPPENING??? as where the fault is e.g. disk full or something else that I don't check for (is that a bug??? Can't check for everything...) and they can't seem to find the actual problem in all the output. I'm done whining now. :-) -Jaap- -- Jaap Vermeulen +--------------------------+ | Sequent Computer Systems | Internet : jaap@sequent.com | Beaverton, Oregon | Uucp : ...uunet!sequent!jaap +--------------------------+ Replied: Tue, 11 May 1993 11:23:08 +0200 Replied: "Jaap Vermeulen <jaap@sequent.com> python-list@cwi.nl" Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA00978 (5.65b/3.8/CWI-Amsterdam); Tue, 11 May 1993 00:49:29 +0200 Received: from eng2.sequent.com by gateway.sequent.com (5.61/1.34) id AA15040; Mon, 10 May 93 15:49:31 -0700 Received: by eng2.sequent.com (5.65/1.34) id AA03845; Mon, 10 May 93 15:22:45 -0700 Message-Id: <9305102222.AA03845@eng2.sequent.com> To: Guido.van.Rossum@cwi.nl Cc: python-list@cwi.nl Subject: Re: Some suggestion for python classes Priority: Normal Precedence: first-class Organization: Sequent Computer Systems, Inc. Service Technology - MailStop: WIL2-610 15450 S.W. Koll Parkway Beaverton, OR 97006-6063 X-Phone: (503) 578-4404 X-Fax: (503) 578-4540 X-Uucp: ...!uunet!sequent!jaap X-Internet: jaap@sequent.com X-Face: C4Cnai$>Eja5I6Vq?(gdN#SXX#`-XgAnmUn&e54sx7@1>q@vkrd_XnH![P>w.:7IJJ;{Bts WJd)u&G!V}0OR?2o5cUgIY}.T{g]PMC=*~]3n_t)S-ZkC(WG}3:#hcA6Oazx:}yc&k,hsF7D},7x>l nyfRjO7$@]fHBN>aC9-M3pKfbYHiy!PWD{_bx~fo})b4tU.;Ao%x[upCI, In-Reply-To: Guido.van.Rossum@cwi.nl's message of Mon, 10 May 1993 21:17:09 +0200. <9305101917.AA29134=guido@voorn.cwi.nl> Date: Mon, 10 May 1993 15:22:44 -0700 From: Jaap Vermeulen <jaap@sequent.com> | Ah, but calling a class method is also used in another situation. The | standard "idiom" for extending a method is as follows: | | class Base: | def doit(self, how): | "do it in a basic way" | | class Derived(Base): | def doit(self, how): | "do a little bit in advance" | Base.doit(self, how) | "do it some more" | | For the interpreter, the call to Base.doit(self, how) in a method of a | Derived instance is indistinguishable from a call somewhere else. And that exactly illustrates the deficiency for not having a "super" operator (I'm jumping ahead to the next issue here), and that is that with multiple base classes you have to choose (or *know*) which base class to invoke (or write a loop to go through all of them). That's why I prefer a "super" functionality where you let the search algorithm find the method (i.e. it would be nice if I could rewrite the above with): def doit(self, how): "do a little but in advance" self^doit(how) "do it some more" I never liked the fact that you have to spell out the base class you're invoking from. | But maybe your example is too simplistic to show what the real problem | is. What does your new() function do between creating the new | instance and returning it? Can't this be done by the instance's | init() function? You convinced me that I don't need this functionality. [About the "super" operator:] | See my example above of how to extend a method in Python. The point | is that the name of the base class is statically known at the point | where you write the code that needs to use it, so there really is no | good reason to dynamically look it up -- you might as well use the | name of the base class. Not with multiple base classes. Besides, you're looking it up dynamically anyways (since the method could be way up in the chain). | You don't give an implementation of your super() workaround -- I have | a feeling that it might fail if there are several layers of derived | classes stacked on top of bar and some of them don't define a new() | method. I don't think so: def super(obj, name): if type(obj) == type(object): sym = 'obj.'+name else: sym = 'obj.__class__.'+name try: try: func = eval(sym) exec('del '+sym) return eval('obj.'+name) finally: exec(sym+'=func') except: return eval('obj.'+name) [About aClass.__name__:] | I don't understand how you want it to work. Do you mean that a class | should be able to decide how it will be printed? How would you use | that? How would you distinguish between the __repr__ method for | instances and the one for the class? Let me rephrase this: Currently what the repr() prints out is of little use to see what it is. It would be *much* nicer, and of much more use if the name could be included in the default representation, both for classes and instances. -Jaap- -- Jaap Vermeulen +--------------------------+ | Sequent Computer Systems | Internet : jaap@sequent.com | Beaverton, Oregon | Uucp : ...uunet!sequent!jaap +--------------------------+ To: Jaap Vermeulen <jaap@sequent.com> Subject: Re: SystemExit In-reply-to: Your message of "Mon, 10 May 1993 13:56:28 MDT." <9305102056.AA18117@eng2.sequent.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Tue, 11 May 1993 09:23:55 +0200 Sender: guido > | Under DOS the _exit() function shouldn't be in os since it isn't in > | the C library either. (Or is it? Then maybe I should add it to the > | DOS version of the posix interface... Please enlighten me, I always > | thought that _exit() is specific to real UNIX and not specified by > | Standard C.) > > I'm not saying it should be there (what does posix mean under msdos?). > I'm saying that os.py callously tried to include it. I got that, but I failed (and still fail) to see what pertinence a bug in os.py has to do with the semantics of sys.exit()... Let's drop this silly argument, OK! > I wouldn't care about the stack trace so much if the format wasn't so > confusing to the ordinary user (yes, other people than myself are using > python programs). Maybe, if the error message could be called out more > and the stack trace could be preceded with some disclaimer, it wouldn't > be so confusing to the ordinary user. They complain to me: WHAT IS > HAPPENING??? as where the fault is e.g. disk full or something else > that I don't check for (is that a bug??? Can't check for everything...) > and they can't seem to find the actual problem in all the output. Excuse me, but it's obvious that the bug is in your program. (Half :-) Read any good, recent book on user interfaces and you'll find that it is unacceptable for users if a program fails with a cryptic error message. I bet that a short cryptic error message (just the exception name) isn't any better than a long one (which includes the stack trace) since in both cases it's communicating at the wrong level, as far as the user is concerned. (And note that a C program would probably have failed silently in the case of disk full, unless there was an explicit check at every write call! Do you like that better?) However, I should take my part of the blame too: it is true that when the stack trace is long the exception type is hard to find. I'll experiment with placing the exception message *after* the stack trace instead of before it. --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA04330 (5.65b/3.8/CWI-Amsterdam); Tue, 11 May 1993 11:23:09 +0200 Received: by voorn.cwi.nl with SMTP id AA00423 (5.65b/3.8/CWI-Amsterdam); Tue, 11 May 1993 11:23:09 +0200 Message-Id: <9305110923.AA00423=guido@voorn.cwi.nl> To: Jaap Vermeulen <jaap@sequent.com> Cc: python-list@cwi.nl Subject: Re: Some suggestion for python classes In-Reply-To: Your message of "Mon, 10 May 1993 15:22:44 MDT." <9305102222.AA03845@eng2.sequent.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Tue, 11 May 1993 11:23:09 +0200 Sender: Guido.van.Rossum@cwi.nl Jaap Vermeulen writes: > And that exactly illustrates the deficiency for not having a "super" > operator (I'm jumping ahead to the next issue here), and that is that > with multiple base classes you have to choose (or *know*) which base > class to invoke (or write a loop to go through all of them). That's > why I prefer a "super" functionality where you let the search algorithm > find the method (i.e. it would be nice if I could rewrite the above with): > > def doit(self, how): > "do a little but in advance" > self^doit(how) > "do it some more" > > I never liked the fact that you have to spell out the base class you're > invoking from. Apart from personal likes and dislikes, I agree that sometimes it is a nuisance having to spell out the name of the base class (especially if it happens to have the form VeryLongModuleName.EvenLongerClassName :-). But this is no more than a nuisance. However, bringing in multiple inheritance changes the matter. (In fact, in a totally different context, I remember having implemented exactly this kind of functionality: "give me the object named X that would be used if there wasn't an X defined locally".) I would still maintain that if you don't know which base class's X you are overriding you are in trouble (i.e. you don't know a basic fact about the code you are using), but I agree that extending a method deserves some special facility. I would like to find a way that doesn't need new syntax. Other requirements are that it should be reasonably compact to write down, it shouldn't require you to quote the attribute name, it shouldn't pollute the instance's name space, nor should it use underscores to avoid namespace pollution. How about a built-in function "super" which returns a pseudo object whose name space is that of its argument except that the derived class is stripped? So you would be able to write super(self).doit(how). (Adding a new built-in function is also a form of namespace pollution, but causes fewer conflicts and no backward compatibility problems since user-defined global and local names have priority over built-in functions.) {I now do believe that your implementation of super works.] > Let me rephrase this: Currently what the repr() prints out is of > little use to see what it is. It would be *much* nicer, and of much > more use if the name could be included in the default representation, > both for classes and instances. This will be fixed for classes when I fix the __name__ attribute. For instances, I don't see how it can be fixed, since instances don't have names when they are created. (If you write "x = C().init()", the instance's name is *not* x -- all of Python's assignment semantics are based on this fact...) Cheers, --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> To: Jaap Vermeulen <jaap@sequent.com> cc: python-list@cwi.nl Subject: Re: Some suggestion for python classes In-reply-to: Your message of "Mon, 10 May 1993 15:22:44 MDT." <9305102222.AA03845@eng2.sequent.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Tue, 11 May 1993 11:23:09 +0200 Sender: guido Jaap Vermeulen writes: > And that exactly illustrates the deficiency for not having a "super" > operator (I'm jumping ahead to the next issue here), and that is that > with multiple base classes you have to choose (or *know*) which base > class to invoke (or write a loop to go through all of them). That's > why I prefer a "super" functionality where you let the search algorithm > find the method (i.e. it would be nice if I could rewrite the above with): > > def doit(self, how): > "do a little but in advance" > self^doit(how) > "do it some more" > > I never liked the fact that you have to spell out the base class you're > invoking from. Apart from personal likes and dislikes, I agree that sometimes it is a nuisance having to spell out the name of the base class (especially if it happens to have the form VeryLongModuleName.EvenLongerClassName :-). But this is no more than a nuisance. However, bringing in multiple inheritance changes the matter. (In fact, in a totally different context, I remember having implemented exactly this kind of functionality: "give me the object named X that would be used if there wasn't an X defined locally".) I would still maintain that if you don't know which base class's X you are overriding you are in trouble (i.e. you don't know a basic fact about the code you are using), but I agree that extending a method deserves some special facility. I would like to find a way that doesn't need new syntax. Other requirements are that it should be reasonably compact to write down, it shouldn't require you to quote the attribute name, it shouldn't pollute the instance's name space, nor should it use underscores to avoid namespace pollution. How about a built-in function "super" which returns a pseudo object whose name space is that of its argument except that the derived class is stripped? So you would be able to write super(self).doit(how). (Adding a new built-in function is also a form of namespace pollution, but causes fewer conflicts and no backward compatibility problems since user-defined global and local names have priority over built-in functions.) {I now do believe that your implementation of super works.] > Let me rephrase this: Currently what the repr() prints out is of > little use to see what it is. It would be *much* nicer, and of much > more use if the name could be included in the default representation, > both for classes and instances. This will be fixed for classes when I fix the __name__ attribute. For instances, I don't see how it can be fixed, since instances don't have names when they are created. (If you write "x = C().init()", the instance's name is *not* x -- all of Python's assignment semantics are based on this fact...) Cheers, --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA23025 (5.65b/3.8/CWI-Amsterdam); Tue, 11 May 1993 21:01:26 +0200 Received: from eng2.sequent.com by gateway.sequent.com (5.61/1.34) id AA19086; Tue, 11 May 93 12:01:21 -0700 Received: by eng2.sequent.com (5.65/1.34) id AA21832; Tue, 11 May 93 12:01:12 -0700 Message-Id: <9305111901.AA21832@eng2.sequent.com> To: Guido.van.Rossum@cwi.nl Cc: python-list@cwi.nl Subject: Re: Some suggestion for python classes Priority: Normal Precedence: first-class Organization: Sequent Computer Systems, Inc. Service Technology - MailStop: WIL2-610 15450 S.W. Koll Parkway Beaverton, OR 97006-6063 X-Phone: (503) 578-4404 X-Fax: (503) 578-4540 X-Uucp: ...!uunet!sequent!jaap X-Internet: jaap@sequent.com X-Face: C4Cnai$>Eja5I6Vq?(gdN#SXX#`-XgAnmUn&e54sx7@1>q@vkrd_XnH![P>w.:7IJJ;{Bts WJd)u&G!V}0OR?2o5cUgIY}.T{g]PMC=*~]3n_t)S-ZkC(WG}3:#hcA6Oazx:}yc&k,hsF7D},7x>l nyfRjO7$@]fHBN>aC9-M3pKfbYHiy!PWD{_bx~fo})b4tU.;Ao%x[upCI, In-Reply-To: Guido.van.Rossum@cwi.nl's message of Tue, 11 May 1993 11:23:09 +0200. <9305110923.AA00423=guido@voorn.cwi.nl> Date: Tue, 11 May 93 12:01:10 PDT From: Jaap Vermeulen <jaap@sequent.com> | write super(self).doit(how). (Adding a new built-in function is also That would be fine. Thanks. | This will be fixed for classes when I fix the __name__ attribute. For | instances, I don't see how it can be fixed, since instances don't have | names when they are created. (If you write "x = C().init()", the I was thinking about prepending the name with 'class' or 'instance', but I can do without the instance name just fine (since I can override it). As an example: >>> class foo: pass >>> foo <class foo at 63a08> >>> foo() <instance foo at 83948> >>> Thanks, -Jaap- -- Jaap Vermeulen +--------------------------+ | Sequent Computer Systems | Internet : jaap@sequent.com | Beaverton, Oregon | Uucp : ...uunet!sequent!jaap +--------------------------+ Replied: Wed, 12 May 1993 08:55:25 +0200 Replied: "Lance Ellinghouse <lance@markv.com> python-list@cwi.nl" Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA04375 (5.65b/3.8/CWI-Amsterdam); Wed, 12 May 1993 00:48:20 +0200 From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: python-list@cwi.nl Subject: MD5 module... Date: Tue, 11 May 93 15:45:42 PDT Message-Id: <9305111545.aa16801@hermix.markv.com> Where can I get the files needed to support the MD5 module? I have the MPZ files from GNU but cannot find the MD5 files..:( Anyone have any ideas?? Can anyone FTP them to me? Thanks, Lance Ellinghouse lance@markv.com Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA29308 (5.65b/3.8/CWI-Amsterdam); Wed, 12 May 1993 08:55:29 +0200 Received: by voorn.cwi.nl with SMTP id AA03307 (5.65b/3.8/CWI-Amsterdam); Wed, 12 May 1993 08:55:25 +0200 Message-Id: <9305120655.AA03307=guido@voorn.cwi.nl> To: Lance Ellinghouse <lance@markv.com> Cc: python-list@cwi.nl Subject: Re: MD5 module... In-Reply-To: Your message of "Tue, 11 May 1993 15:45:42 MDT." <9305111545.aa16801@hermix.markv.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Wed, 12 May 1993 08:55:25 +0200 Sender: Guido.van.Rossum@cwi.nl > Where can I get the files needed to support the MD5 module? > I have the MPZ files from GNU but cannot find the MD5 files..:( > > Anyone have any ideas?? > > Can anyone FTP them to me? >From the Makefile (I agree not a perfect place to look for an ftp pointer :-): # This option enables access to the RSA Data Security, Inc. MD5 # Message-Digest Algorithm. This requires the files md5.c and md5.h # which are included in the file md5.doc ftp'able from rsa.com. BTW there's a new MPZ out -- anyone care to test it out? (I have little time nor a direct need for it...) --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> To: Lance Ellinghouse <lance@markv.com> cc: python-list@cwi.nl Subject: Re: MD5 module... In-reply-to: Your message of "Tue, 11 May 1993 15:45:42 MDT." <9305111545.aa16801@hermix.markv.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Wed, 12 May 1993 08:55:25 +0200 Sender: guido > Where can I get the files needed to support the MD5 module? > I have the MPZ files from GNU but cannot find the MD5 files..:( > > Anyone have any ideas?? > > Can anyone FTP them to me? From the Makefile (I agree not a perfect place to look for an ftp pointer :-): # This option enables access to the RSA Data Security, Inc. MD5 # Message-Digest Algorithm. This requires the files md5.c and md5.h # which are included in the file md5.doc ftp'able from rsa.com. BTW there's a new MPZ out -- anyone care to test it out? (I have little time nor a direct need for it...) --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from att-out.att.com by charon.cwi.nl with SMTP id AA00763 (5.65b/3.8/CWI-Amsterdam); Wed, 12 May 1993 09:20:22 +0200 From: hzsbg01!jbuhrma@hvgtw.att.com Received: from hzsbc03 by hzsbg01 (4.1/SMI-4.1) id AA09850; Wed, 12 May 93 09:16:58 +0200 Date: Wed, 12 May 93 09:16:58 +0200 Original-From: hzsbg01!jbuhrma Message-Id: <9305120716.AA09850@hzsbg01> To: lance@markv.com Subject: Re: MD5 module... Cc: python-list@cwi.nl > Where can I get the files needed to support the MD5 module? > I have the MPZ files from GNU but cannot find the MD5 files..:( You can ftp it from `rsa.com'. The file is called `md5.doc'. You'll have to extract the C-sources from this document. The sources also contain a test program; the output from this test program should be exact the same as the output from the Python md5 test program. Regards, -- Jan-Hein Buhrman -- AT&T Huizen NL -- <jbuhrma%hzsbg01@hvlpa.att.com> -- ---------------------- +31 35 87.4278 --- ...!att!hvlpa!hzsbg01!jbuhrma --- usage: prog [option(s)] [--] [arg(s) ...] Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA01455 (5.65b/3.8/CWI-Amsterdam); Wed, 12 May 1993 09:33:14 +0200 Received: by voorn.cwi.nl with SMTP id AA03463 (5.65b/3.8/CWI-Amsterdam); Wed, 12 May 1993 09:33:13 +0200 Message-Id: <9305120733.AA03463=guido@voorn.cwi.nl> To: python-list@cwi.nl Subject: Oops, super() can't work! From: Guido.van.Rossum@cwi.nl X-Organization: CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Wed, 12 May 1993 09:33:13 +0200 Sender: Guido.van.Rossum@cwi.nl I had a hunch about Jaap's super() method that it wouldn't work with multiple nested levels of extending the same method. Now I have proof. The problem occurs when A is a base class of B and B is a base class of C, and each of B and C have a method with the same name that extends their base class's version. Now if we have an instance of C, the C version will call the B version alright, but the call to super() in the B version will not retrieve the A version of the method -- it will retrieve the B version again. This is because even during execution of the B method, the type of self is still C. See example after my signature. A built-in super() function would have the same problem -- the information about the current class is simply not available (and Python's dynamic object model makes it even possible to have a function being included as a method in two different classes!). So I'll have to resort to my gut feeling about this: if you don't know which base class's method you're overriding you don't know what you're doing! The only way to fix this would be to make the interpreter aware of the class to which a method belongs, which would require a major reorganization of the interpreter and code generator. How does Smalltalk do this? I know that Simula has a "super" construct in the language but there it is solved at compile time. In C++ you have to name the base class explicitly, as in Python. I believe it's the same in Modula-3 (from which I borrowed more than one idea for Python). My only hope is that perhaps Steve Myale of U of Virginia has already fixed this in his mods to eliminate self and introduce private and public variables (and much more). Steve? (We'll need to discuss your changes to the language on the list anyway, before they can become an official part of it.) --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> ======================================================================== class A: def meth(self): print 'A.self(', self, ')' class B(A): def meth(self): print 'B.self(', self, ')' super(self, 'meth')() class C(B): def meth(self): print 'C.self(', self, ')' super(self, 'meth')() def super(obj, name): # Simplified version of Jaap's super(), for instances only! sym = 'obj.'+name try: try: func = eval(sym) exec('del '+sym) return eval('obj.'+name) finally: exec(sym+'=func') except: return eval('obj.'+name) print 'test A:' a = A() a.meth() print 'test B:' b = B() b.meth() print 'test C:' c = C() c.meth() ======================================================================== test A: A.self( <instance object at 100e74d0> ) test B: B.self( <instance object at 100e74b0> ) B.self( <instance object at 100e74b0> ) B.self( <instance object at 100e74b0> ) B.self( <instance object at 100e74b0> ) . . . To: python-list Subject: Oops, super() can't work! From: Guido.van.Rossum@cwi.nl X-Organization: CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Wed, 12 May 1993 09:33:13 +0200 Sender: guido I had a hunch about Jaap's super() method that it wouldn't work with multiple nested levels of extending the same method. Now I have proof. The problem occurs when A is a base class of B and B is a base class of C, and each of B and C have a method with the same name that extends their base class's version. Now if we have an instance of C, the C version will call the B version alright, but the call to super() in the B version will not retrieve the A version of the method -- it will retrieve the B version again. This is because even during execution of the B method, the type of self is still C. See example after my signature. A built-in super() function would have the same problem -- the information about the current class is simply not available (and Python's dynamic object model makes it even possible to have a function being included as a method in two different classes!). So I'll have to resort to my gut feeling about this: if you don't know which base class's method you're overriding you don't know what you're doing! The only way to fix this would be to make the interpreter aware of the class to which a method belongs, which would require a major reorganization of the interpreter and code generator. How does Smalltalk do this? I know that Simula has a "super" construct in the language but there it is solved at compile time. In C++ you have to name the base class explicitly, as in Python. I believe it's the same in Modula-3 (from which I borrowed more than one idea for Python). My only hope is that perhaps Steve Myale of U of Virginia has already fixed this in his mods to eliminate self and introduce private and public variables (and much more). Steve? (We'll need to discuss your changes to the language on the list anyway, before they can become an official part of it.) --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> ======================================================================== class A: def meth(self): print 'A.self(', self, ')' class B(A): def meth(self): print 'B.self(', self, ')' super(self, 'meth')() class C(B): def meth(self): print 'C.self(', self, ')' super(self, 'meth')() def super(obj, name): # Simplified version of Jaap's super(), for instances only! sym = 'obj.'+name try: try: func = eval(sym) exec('del '+sym) return eval('obj.'+name) finally: exec(sym+'=func') except: return eval('obj.'+name) print 'test A:' a = A() a.meth() print 'test B:' b = B() b.meth() print 'test C:' c = C() c.meth() ======================================================================== test A: A.self( <instance object at 100e74d0> ) test B: B.self( <instance object at 100e74b0> ) B.self( <instance object at 100e74b0> ) B.self( <instance object at 100e74b0> ) B.self( <instance object at 100e74b0> ) . . . Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA08135 (5.65b/3.8/CWI-Amsterdam); Wed, 12 May 1993 12:48:25 +0200 Received: by voorn.cwi.nl with SMTP id AA04360 (5.65b/3.8/CWI-Amsterdam); Wed, 12 May 1993 12:48:24 +0200 Message-Id: <9305121048.AA04360=guido@voorn.cwi.nl> To: python-list@cwi.nl Subject: continuation lines From: Guido.van.Rossum@cwi.nl X-Organization: CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Wed, 12 May 1993 12:48:23 +0200 Sender: Guido.van.Rossum@cwi.nl Someone gave me a tiny mod (about 15 lines) to the tokenizer that makes breaking long lines easier. The mod makes it possible to omit the backslash when breaking a line *inside parentheses*. The mod keeps track of the accumulated nesting level of all sorts of parentheses: () [] {}, and suppresses the NEWLINE token (and the check for indentation level)when the parentheses nesting level is greater than zero. It relies on the parser to make sure that parentheses occur in properly matched pairs and at syntactically legal places. The net effect is that you can write things like function_with_many_arguments(the_first_argument, the_second_argument, the_third_argument, the_fourth_argument, the_last_argument) or initialize lists as follows: months = ['Jan', 'Feb', 'Mar', # first Q 'Apr', 'May', 'Jun', # second Q 'Jul', 'Aug', 'Sep', # third Q 'Oct', 'Nov', 'Dec'] # fourth Q (Code using backslashes still works, but note that a line can't have a backslash *and* a comment, so there's a definite improvement here.) A drawback is that if you accidentally forget a closing parenthesis, you might get a syntax error on the next line or even further down. Usually this will be on the first token of the next line though (since most tokens that can start a statement can't continue an expression -- the exception being open parentheses and brackets). A way to alleviate this problem would be to print the entire current *logical* line when a syntax error has occurred. Ideally, one would like a syntax where a line can be broken without a backslash anywhere where the syntax doesn't allow a newline token. This would allow things like if very_long_condition and _another_long_condition and yet_another_condition and another_one_again: do_something_very_carefully() and a_variable_with_an_excruciatingly_long_identifier = an_expression_that_is_almost_equally_horrible (but still not this: print 1, 2, 3, 4, 5, 6 nor x = 1, 2, 3, 4, 5, 6 -- do you see why not?) However, such a change would require a much bigger change to the parser and tokenizer (apart from the difficulties in spelling out *exactly* what the rules would be, for future generations). I feel that this mod would be a useful addition to Python (also it fits nicely in the tradition of carefully trading certain principles for implementability). What do you think? --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from relay.surfnet.nl by charon.cwi.nl with SMTP id AA08710 (5.65b/3.8/CWI-Amsterdam); Wed, 12 May 1993 13:16:43 +0200 X400-Received: by mta relay.surfnet.nl in /PRMD=surf/ADMD=400net/C=nl/; Relayed; Wed, 12 May 1993 13:16:00 +0200 X400-Received: by /PRMD=surf/ADMD=400net/C=nl/; Relayed; Wed, 12 May 1993 13:17:24 +0200 X400-Received: by /PRMD=uk.ac/ADMD= /C=gb/; Relayed; Wed, 12 May 1993 13:15:15 +0200 X400-Received: by /PRMD=UK.AC/ADMD= /C=GB/; Relayed; Wed, 12 May 1993 13:15:03 +0200 X400-Received: by /PRMD=UK.AC/ADMD= /C=GB/; Relayed; Wed, 12 May 1993 13:14:52 +0200 X400-Received: by /PRMD=UK.AC/ADMD= /C=GB/; Relayed; Wed, 12 May 1993 13:14:52 +0200 Date: Wed, 12 May 1993 13:14:52 +0200 X400-Originator: peter%robots.oxford.ac.uk@prg.oxford.ac.uk X400-Recipients: Guido.van.Rossum@cwi.nl X400-Mts-Identifier: [/PRMD=UK.AC/ADMD= /C=GB/;<9305121114.AA08646@moth.robots.] X400-Content-Type: P2-1984 (2) Content-Identifier: Re: continuat... From: peter@robots.oxford.ac.uk Message-Id: <9305121114.AA08646@moth.robots.ox.ac.uk> To: Guido.van.Rossum@cwi.nl Subject: Re: continuation lines It seems much nicer to have your proposed change, instead of typing backslash each time. But I think that having a better error report may (_slightly_) outweigh the pain of backslashing. It's a very marginal decision -- maybe just toss a coin :-) Pete. Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA16642 (5.65b/3.8/CWI-Amsterdam); Wed, 12 May 1993 17:44:05 +0200 Received: from eng2.sequent.com by gateway.sequent.com (5.61/1.34) id AA27808; Wed, 12 May 93 08:44:07 -0700 Received: by eng2.sequent.com (5.65/1.34) id AA03222; Wed, 12 May 93 08:44:01 -0700 Message-Id: <9305121544.AA03222@eng2.sequent.com> To: Guido.van.Rossum@cwi.nl Cc: python-list@cwi.nl Subject: Re: continuation lines Priority: Normal Precedence: first-class Organization: Sequent Computer Systems, Inc. Service Technology - MailStop: WIL2-610 15450 S.W. Koll Parkway Beaverton, OR 97006-6063 X-Phone: (503) 578-4404 X-Fax: (503) 578-4540 X-Uucp: ...!uunet!sequent!jaap X-Internet: jaap@sequent.com X-Face: C4Cnai$>Eja5I6Vq?(gdN#SXX#`-XgAnmUn&e54sx7@1>q@vkrd_XnH![P>w.:7IJJ;{Bts WJd)u&G!V}0OR?2o5cUgIY}.T{g]PMC=*~]3n_t)S-ZkC(WG}3:#hcA6Oazx:}yc&k,hsF7D},7x>l nyfRjO7$@]fHBN>aC9-M3pKfbYHiy!PWD{_bx~fo})b4tU.;Ao%x[upCI, In-Reply-To: Guido.van.Rossum@cwi.nl's message of Wed, 12 May 1993 12:48:23 +0200. <9305121048.AA04360=guido@voorn.cwi.nl> Date: Wed, 12 May 1993 08:44:00 -0700 From: Jaap Vermeulen <jaap@sequent.com> | What do you think? I think that is great, because I already ran into the inconvenience of the backslash notation. Most long lines are within parenthesis, so the mod it very useful! -Jaap- -- Jaap Vermeulen +--------------------------+ | Sequent Computer Systems | Internet : jaap@sequent.com | Beaverton, Oregon | Uucp : ...uunet!sequent!jaap +--------------------------+ Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA16837 (5.65b/3.8/CWI-Amsterdam); Wed, 12 May 1993 17:52:51 +0200 Received: from eng2.sequent.com by gateway.sequent.com (5.61/1.34) id AA28300; Wed, 12 May 93 08:52:50 -0700 Received: by eng2.sequent.com (5.65/1.34) id AA04404; Wed, 12 May 93 08:52:40 -0700 Message-Id: <9305121552.AA04404@eng2.sequent.com> To: Guido.van.Rossum@cwi.nl Cc: python-list@cwi.nl Subject: Re: Oops, super() can't work! Priority: Normal Precedence: first-class Organization: Sequent Computer Systems, Inc. Service Technology - MailStop: WIL2-610 15450 S.W. Koll Parkway Beaverton, OR 97006-6063 X-Phone: (503) 578-4404 X-Fax: (503) 578-4540 X-Uucp: ...!uunet!sequent!jaap X-Internet: jaap@sequent.com X-Face: C4Cnai$>Eja5I6Vq?(gdN#SXX#`-XgAnmUn&e54sx7@1>q@vkrd_XnH![P>w.:7IJJ;{Bts WJd)u&G!V}0OR?2o5cUgIY}.T{g]PMC=*~]3n_t)S-ZkC(WG}3:#hcA6Oazx:}yc&k,hsF7D},7x>l nyfRjO7$@]fHBN>aC9-M3pKfbYHiy!PWD{_bx~fo})b4tU.;Ao%x[upCI, In-Reply-To: Guido.van.Rossum@cwi.nl's message of Wed, 12 May 1993 09:33:13 +0200. <9305120733.AA03463=guido@voorn.cwi.nl> Date: Wed, 12 May 1993 08:52:38 -0700 From: Jaap Vermeulen <jaap@sequent.com> | name that extends their base class's version. Now if we have an | instance of C, the C version will call the B version alright, but the | call to super() in the B version will not retrieve the A version of | the method -- it will retrieve the B version again. This is because | even during execution of the B method, the type of self is still C. Damn! You're right. What a drag. The only thing you could try to do is matching the actual code object, but that becomes a kludge. | reorganization of the interpreter and code generator. How does | Smalltalk do this? I know that Simula has a "super" construct in the No idea. But Smalltalk is inherently organized and structured differently. | My only hope is that perhaps Steve Myale of U of Virginia has already | fixed this in his mods to eliminate self and introduce private and | public variables (and much more). Steve? (We'll need to discuss your | changes to the language on the list anyway, before they can become an | official part of it.) I would like to see a proposal for these changes. I'm very much interested. I guess the bottom line of this discussion is: Some of my proposed changes would have been nice and transparent to the programmer, however, I'm sure I can live without. I'll soon be implementing another piece of code using classes extensively, so, again, I'll try to gauge how well Python is holding up! Thanks for this discussion, -Jaap- -- Jaap Vermeulen +--------------------------+ | Sequent Computer Systems | Internet : jaap@sequent.com | Beaverton, Oregon | Uucp : ...uunet!sequent!jaap +--------------------------+ Received: from uunet.ca by charon.cwi.nl with SMTP id AA16737 (5.65b/3.8/CWI-Amsterdam); Wed, 12 May 1993 17:47:43 +0200 Received: from sni.ca ([192.75.236.203]) by mail.uunet.ca with SMTP id <9644(1)>; Wed, 12 May 1993 11:47:35 -0400 Received: from radium.sni.ca by sni.ca (5.61/smail2.5/07-11-92) id AA03971; Wed, 12 May 93 11:53:31 -0400 Received: by radium.sni.CA (5.61/smail2.5/02-09-92) id AA11382; Wed, 12 May 93 11:53:27 -0400 Date: Wed, 12 May 1993 11:53:27 -0400 From: tracy@radium.uucp (Tracy Tims) Message-Id: <9305121553.AA11382@radium.sni.CA> To: Guido.van.Rossum@cwi.nl In-Reply-To: Guido.van.Rossum@cwi.nl's message of Wed, 12 May 1993 06:48:23 -0400 <9305121048.AA04360=guido@voorn.cwi.nl> Subject: continuation lines I like the second version best, where newlines don't terminate lines where the syntax doesn't allow it. However, there is no reason why you can't make the changes in two stages. If you don't have time to rewrite the parser, just add the parenthesis-balancing mod for now. Add the rest when you have time. The changes don't break old code. I seem to write a number of tables here and there in my code, and the biggest drawback to maintaining them is continuations, so even the parenthesis-balancing is a big win. Tracy Tims PS. I'm still working on the whole symbolic regular expression thing, but I've just resigned from my current job. I should have a bit more time in my new job, but I'll be off the net for awhile. I should be able to make some progress, but it will be harder to tell people about it. Received: from optima.CS.Arizona.EDU by charon.cwi.nl with SMTP id AA17401 (5.65b/3.8/CWI-Amsterdam); Wed, 12 May 1993 18:19:31 +0200 Received: from chuckwalla.CS.Arizona.EDU by optima.CS.Arizona.EDU (5.65c/15) via SMTP id AA24791; Wed, 12 May 1993 09:19:12 MST Date: Wed, 12 May 1993 09:19:10 MST From: "Clint Jeffery" <cjeffery@cs.arizona.edu> Message-Id: <199305121619.AA18230@chuckwalla.cs.arizona.edu> Received: by chuckwalla.cs.arizona.edu; Wed, 12 May 1993 09:19:10 MST To: jaap@sequent.com, Guido.van.Rossum@cwi.nl In-Reply-To: Jaap Vermeulen's message of Wed, 12 May 1993 08:52:38 -0700 <9305121552.AA04404@eng2.sequent.com> Subject: Oops, super() can't work! Well, languages that have "class variables" can define a class variable that knows the class of the method that is executing, and implement "super" functionality on top of that. But personally I agree with Guido's sentiments about the whole thing. If you don't know which method you are going to get using super, aren't you liable to get the wrong one? Replied: Fri, 14 May 1993 11:22:22 +0200 Replied: "Tim Peters <tim@ksr.com> " Received: from hopscotch.ksr.com by charon.cwi.nl with SMTP id AA17722 (5.65b/3.8/CWI-Amsterdam); Thu, 13 May 1993 22:33:28 +0200 Received: from ksr.com (frankenstein.ksr.com) by hopscotch.ksr.com with SMTP id AA00718; Thu, 13 May 1993 16:33:06 -0400 Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA16262; Thu, 13 May 93 16:34:03 EDT Received: by kaos.ksr.com (4.1/KSR-2.0) id AA14835; Thu, 13 May 93 16:33:59 EDT Message-Id: <9305132033.AA14835@kaos.ksr.com> To: python-list@cwi.nl Subject: Re: continuation lines Date: Thu, 13 May 93 16:33:58 -0400 From: Tim Peters <tim@ksr.com> I think it's a neat idea. Especially this part: > ... or initialize lists as follows: > > months = ['Jan', 'Feb', 'Mar', # first Q > 'Apr', 'May', 'Jun', # second Q > 'Jul', 'Aug', 'Sep', # third Q > 'Oct', 'Nov', 'Dec'] # fourth Q > > (Code using backslashes still works, but note that a line can't have a > backslash *and* a comment, so there's a definite improvement here.) I see I've accumulated a lot of initializers like ix = [ 0x418, 0x280, 0x778, 0x58f, 0x3f1, \ 0x0c0, 0x241, 0x7c1, 0x60f, 0x613, \ 0x67f, 0x4f7, 0x2cd, 0x425, 0x4d3, \ 0x75a, 0x6d8, 0x601, 0x320, 0x1a9, ] and I bet an embedded comment or two wouldn't have hurt them <snort>. One downside: it would take a major rewrite of python-mode.el to deal with this correctly. E.g., now a line is a continuation line if & only if it's not the first line in the file, and the preceding line ends with a backslash that's not part of a comment. A simple-enough regexp can deal with that reliably, & Python mode takes full advantage of that. When the definition changes to require consideration of bracket nesting depth too, regexps no longer suffice, and the alternatives are very messy and/or slow (e.g., look up the docs for parse-partial-sexp, then realize they explained it as clearly as they could given the function's inherent complexity <0.9 grin>). Without such changes, Python mode will treat the new-style continuation lines as if they were not continuation lines, and that has some irritating aspects. too-hard-to-fix-in-the-time-i-can-make-so-i'll-call-it-a-feature<smile>- ly y'rs - tim, who likes the idea very much anyway Replied: Fri, 14 May 1993 10:06:37 +0200 Replied: "Lance Ellinghouse <lance@markv.com> python-list" Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA22949 (5.65b/3.8/CWI-Amsterdam); Fri, 14 May 1993 00:28:22 +0200 From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: Guido.van.Rossum@cwi.nl Subject: Re: continuation lines Cc: python-list@cwi.nl Date: Thu, 13 May 93 15:23:56 PDT Message-Id: <9305131524.aa02090@hermix.markv.com> > I feel that this mod would be a useful addition to Python (also it > fits nicely in the tradition of carefully trading certain principles > for implementability). > > What do you think? I would very much like to see this mod posted somewhere as this would make some lists that I am building up (100+ elements) much easier to code! I also think it fits very nicely with other languages... The current behavior is one that I did not like in Tcl (Tool Command Language) and one reason why I moved to PYTHON (besides PYTHON's types and ability to have custom types beyond just strings, and the module ideas in PYTHON, and a bunch of other things like speed of PYTHON :) )... Lance Ellinghouse lance@markv.com Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA13644 (5.65b/3.8/CWI-Amsterdam); Fri, 14 May 1993 10:06:40 +0200 Received: by voorn.cwi.nl with SMTP id AA10842 (5.65b/3.8/CWI-Amsterdam); Fri, 14 May 1993 10:06:38 +0200 Message-Id: <9305140806.AA10842=guido@voorn.cwi.nl> To: Lance Ellinghouse <lance@markv.com> Cc: python-list@cwi.nl Subject: Re: continuation lines In-Reply-To: Your message of "Thu, 13 May 1993 15:23:56 MDT." <9305131524.aa02090@hermix.markv.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Fri, 14 May 1993 10:06:38 +0200 Sender: Guido.van.Rossum@cwi.nl > I would very much like to see this mod posted somewhere as this would > make some lists that I am building up (100+ elements) much easier to > code! I also think it fits very nicely with other languages... Unfortunately the author of the mod found it necessary to reformat the file before making the changes :-(. I have retrofitted it in my current source but that also contains another fix, so I can't guarantee that the following diff will work with a clean 0.9.8 source. Below is the diff for tokenizer.c; you also need to add "int level;" to the end of the struct defined in tokenizer.h. --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> *** 2.12 1993/05/12 08:24:17 --- tokenizer.c 1993/05/12 11:35:42 *************** *** 111,112 **** --- 111,113 ---- tok->lineno = 0; + tok->level = 0; return tok; *************** *** 392,394 **** } ! if (!blankline) { if (col == tok->indstack[tok->indent]) { --- 393,395 ---- } ! if (!blankline && tok->level == 0) { if (col == tok->indstack[tok->indent]) { *************** *** 485,487 **** tok->atbol = 1; ! if (blankline) goto nextline; --- 486,488 ---- tok->atbol = 1; ! if (blankline || tok->level > 0) goto nextline; *************** *** 612,613 **** --- 613,628 ---- tok_backup(tok, c2); + } + + /* Keep track of parenteses nesting level */ + switch (c) { + case '(': + case '[': + case '{': + tok->level++; + break; + case ')': + case ']': + case '}': + tok->level--; + break; } To: python-list Subject: __init__ From: Guido.van.Rossum@cwi.nl X-Organization: CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Tue, 18 May 1993 00:37:00 +0200 Sender: guido The next Python release will have a feature that makes initialization of class instances a little easier. If a class defines a method named __init__ then this method will be called when an instance of that class is created. If you pass any arguments to the class these will be passed on to the __init__ method. For example: class Window: def __init__(self, name): self.name = name "other initializations" "other methods" x = Window('testWindow') Now think of derived classes. If the derived class also calls a method named __init__, it will be called. But shouldn't the base class's __init__ be called first? Any C++ programmer would recognize that __init__ is really a "constructor", and in C++ constructors of base classes are guaranteed to be called before the derived class constructor is called. In old Python, where instead of __init__ there is a convention to have a method init which is explicitly called by the caller at construction time (e.g. x = Window().init('testWindow')) it is the responsibility of the derived init method to also call the base class init method (and so on recursively). First I thought I could improve the situation, by walking the inheritance tree at creation time ald call all __init__ methods that I found, in a bottom-up order. But then I realized that I had the same problem as C++: how to pass each __init__ method its rightful arguments? In C++ this is solved with special syntax that is only required if the base constructors need any arguments, but that's beyond the capabilities of the Python interpreter because it's impossible to tell how many arguments a function without actually calling it. There are several ways out. One, only call the derived class' __init__ method and hope that it will call the base class' __init__ method(s). Pro: simple to imeplement. Con: no real guarantee that a base class' __init__ is called. Two, pass the same arguments to all __init__ methods. Pro: still easy to implement, plus guarantees call to base class' __init__ is called. Con: sometimes the derived class needs extra arguments, but adding them to its __init__ method will break the derived class' __init__ method, so kludges would be necessary. I presonally think solution One isn't so bad, especially since one can expect a little extra care from a (derived) class implementer. (And Python's type checking isn't really strong enough to prevent major screw-ups anyway.) I also think the problem of solution Two is a real problem and I don't really see how to solve it. Anybody have a different opinion or a clever idea? Please speak up! --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from optima.CS.Arizona.EDU by charon.cwi.nl with SMTP id AA00825 (5.65b/3.8/CWI-Amsterdam); Tue, 18 May 1993 00:59:00 +0200 Received: from chuckwalla.CS.Arizona.EDU by optima.cs.arizona.edu (5.65c/15) via SMTP id AA29473; Mon, 17 May 1993 15:58:57 MST Date: Mon, 17 May 1993 15:58:56 MST From: "Clint Jeffery" <cjeffery@cs.arizona.edu> Message-Id: <199305172258.AA23439@chuckwalla.cs.arizona.edu> Received: by chuckwalla.cs.arizona.edu; Mon, 17 May 1993 15:58:56 MST To: Guido.van.Rossum@cwi.nl Cc: python-list@cwi.nl In-Reply-To: Guido.van.Rossum@cwi.nl's message of Tue, 18 May 1993 00:37:00 +0200 <9305172237.AA01454=guido@voorn.cwi.nl> Subject: __init__ This business about __init__'s in derived classes calling __init__'s in superclasses is bumping up against a fairly general problem (method combination). The problem is more than just passing everyone the right arguments, it is also the case that some hiearchies want to do it bottom-up while other perfectly reasonable hierarchies want to do it top-down. I wouldn't look to C++ as a role model for this! Check out Flavors (an OO Lisp dialect) or other dynamic OO languages for better approaches. Clint Jeffery cjeffery@cs.arizona.edu Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA13655 (5.65b/3.8/CWI-Amsterdam); Tue, 18 May 1993 02:31:19 +0200 Received: from eng2.sequent.com by gateway.sequent.com (5.61/1.34) id AA13152; Mon, 17 May 93 17:31:14 -0700 Received: by eng2.sequent.com (5.65/1.34) id AA17171; Mon, 17 May 93 17:31:13 -0700 Message-Id: <9305180031.AA17171@eng2.sequent.com> To: Guido.van.Rossum@cwi.nl Cc: python-list@cwi.nl Subject: Re: __init__ Priority: Normal Precedence: first-class Organization: Sequent Computer Systems, Inc. Service Technology - MailStop: WIL2-610 15450 S.W. Koll Parkway Beaverton, OR 97006-6063 X-Phone: (503) 578-4404 X-Fax: (503) 578-4540 X-Uucp: ...!uunet!sequent!jaap X-Internet: jaap@sequent.com X-Face: C4Cnai$>Eja5I6Vq?(gdN#SXX#`-XgAnmUn&e54sx7@1>q@vkrd_XnH![P>w.:7IJJ;{Bts WJd)u&G!V}0OR?2o5cUgIY}.T{g]PMC=*~]3n_t)S-ZkC(WG}3:#hcA6Oazx:}yc&k,hsF7D},7x>l nyfRjO7$@]fHBN>aC9-M3pKfbYHiy!PWD{_bx~fo})b4tU.;Ao%x[upCI, In-Reply-To: Guido.van.Rossum@cwi.nl's message of Tue, 18 May 1993 00:37:00 +0200. <9305172237.AA01454=guido@voorn.cwi.nl> Date: Mon, 17 May 1993 17:31:12 -0700 From: Jaap Vermeulen <jaap@sequent.com> | Anybody have a different opinion or a clever idea? Please speak up! No clever idea's (I never had :-), but certainly an opinion! Looks like option 2 is asking for trouble, so I recommend option 1). What is the reason behind this change? Just to be able to call class_name(arguments) and getting an instance, or are there other reasons as well? On another note: How are the __len__ and other special functoins implemented? Is there considarable overhead for using these function instead of the built-in ones, or should there be almost no difference? Just curious... Thanks, -Jaap- -- Jaap Vermeulen +--------------------------+ | Sequent Computer Systems | Internet : jaap@sequent.com | Beaverton, Oregon | Uucp : ...uunet!sequent!jaap +--------------------------+ Received: from schelvis.cwi.nl by charon.cwi.nl with SMTP id AA24143 (5.65b/3.8/CWI-Amsterdam); Tue, 18 May 1993 10:07:33 +0200 Received: by schelvis.cwi.nl with SMTP id AA08705 (5.65b/3.8/CWI-Amsterdam); Tue, 18 May 1993 10:07:31 +0200 Message-Id: <9305180807.AA08705=jack@schelvis.cwi.nl> To: Guido.van.Rossum@cwi.nl Cc: python-list@cwi.nl Subject: Re: __init__ In-Reply-To: Message by Guido.van.Rossum@cwi.nl , Tue, 18 May 1993 00:37:00 +0200 , <9305172237.AA01454=guido@voorn.cwi.nl> Organisation: Multi-media group, CWI, Kruislaan 413, Amsterdam Phone: +31 20 5924098(work), +31 20 5924199 (fax), +31 20 6160335(home) X-Last-Band-Seen: Down by Law (29-4, Melkweg) X-Mini-Review: pretty boring. Date: Tue, 18 May 1993 10:07:30 +0200 From: Jack Jansen <Jack.Jansen@cwi.nl> How about a little bit of extra syntax that allows the programmer to declare whether python should call the base class __init__()'s directly or not? So, something like: class Base(): def __init__(self, arg): ... return self class Der_one(Base): def __init__(self, arg): # Base.__init__ called automatically ... return self class Der_two(*Base): def __init__(self, arg1, arg2): self = Base.__init__(self,arg1) # Not called automatically ... return self -- Jack Jansen | If I can't dance I don't want to be part of Jack.Jansen@cwi.nl | your revolution -- Emma Goldman uunet!cwi.nl!jack G=Jack;S=Jansen;O=cwi;PRMD=surf;ADMD=400net;C=nl Received: from lebe.iaci.kun.nl by charon.cwi.nl with SMTP id AA20905 (5.65b/3.8/CWI-Amsterdam); Tue, 18 May 1993 08:04:44 +0200 Received: by lebe.local (5.57/Ultrix3.0-C) id AA10333; Tue, 18 May 93 08:04:07 +0200 Message-Id: <9305180604.AA10333@lebe.local> To: Guido.van.Rossum@cwi.nl Cc: python-list@cwi.nl From: hegt@lebe.iaci.kun.nl Subject: Re: __init__ In-Reply-To: Your message of "Tue, 18 May 93 00:37:00 METDST." <9305172237.AA01454=guido@voorn.cwi.nl> Date: Tue, 18 May 93 08:04:05 CDT Sender: hegt@lebe.local In message <9305172237.AA01454=guido@voorn.cwi.nl> you write: >The next Python release will have a feature that makes initialization >of class instances a little easier. If a class defines a method named >__init__ then this method will be called when an instance of that >class is created. If you pass any arguments to the class these will >be passed on to the __init__ method. For example: > .... > >Anybody have a different opinion or a clever idea? Please speak up! > >--Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> How about using the type of main(argc,argv) solution, i.e. provide every __init__ method with a list containing the real arguments, from which it can take what it understands? I have no idea about the implementation aspects of such a solution, it is just a thought ... Rob Hegt Replied: Tue, 18 May 1993 16:32:23 +0200 Replied: "Chris Hoffmann <choffman@vicorp.com> python-list" Received: from relay1.UU.NET by charon.cwi.nl with SMTP id AA03138 (5.65b/3.8/CWI-Amsterdam); Tue, 18 May 1993 15:56:15 +0200 Received: from vicorp.com (via vicorp.vicorp.com) by relay1.UU.NET with SMTP (5.61/UUNET-internet-primary) id AA01677; Tue, 18 May 93 09:56:13 -0400 Received: from ithaca.vicorp.com by vicorp.com (4.1/SMI-4.1) id AA20902; Tue, 18 May 93 09:56:08 EDT Date: Tue, 18 May 93 09:56:07 EDT From: Chris Hoffmann <choffman@vicorp.com> Message-Id: <9305181356.AA20902@vicorp.com> To: python-list@cwi.nl Subject: __init__ I prefer option (1), have the derived class explicitly call the initializers for the base classes. I don't like the main(argc,argv) suggestion of Rob Hegt as the arguments for the base class initializers may not even be in the arguments for the derived class--the derived class may want to synthesize them from the arguments it receives. Personally, I think the idea that the derived class must explicitly initialize the base class(es) and there are no implicit initializations is perfectly acceptable. It's simple to explain and the code is easier to understand (at least for me) as there are no "hidden" function calls. In other words, if you're going to have to allow explicit base class initializations anyway, and I think you do, make them always required. I'd like python to stay as lean as possible, so I'd rather not clutter the language by having to support implicit initializations. (There are plenty of more useful things we can choose from when it comes time to clutter!) By the way, will there be a __del__(self) method that is called at destruction time? My thought on this was that when python sees that an object should be garbage collected, it calls the object's __del__ method (if any) before actually destroying it. Of course the interpreter would have to check the object's refcount after calling the function, as the method may have caused the object to be referenced by some other object. I don't really have a good example of why you'd want this, other than for creating classes that keep track of how many instances of the class exist. Perhaps someone else can think of a good reason for having it. It just seems that if you have a function that is called at object creation that you should have one that is called at object destruction as well. Chris ----------------------------------------------------------------------------- Chris Hoffmann VI Corporation choffman@vicorp.com 47 Pleasant St. Northampton MA 01060 Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA04182 (5.65b/3.8/CWI-Amsterdam); Tue, 18 May 1993 16:32:25 +0200 Received: by voorn.cwi.nl with SMTP id AA04906 (5.65b/3.8/CWI-Amsterdam); Tue, 18 May 1993 16:32:24 +0200 Message-Id: <9305181432.AA04906=guido@voorn.cwi.nl> To: Chris Hoffmann <choffman@vicorp.com> Cc: python-list@cwi.nl Subject: Re: __init__ and __del__ In-Reply-To: Your message of "Tue, 18 May 1993 09:56:07 MDT." <9305181356.AA20902@vicorp.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Tue, 18 May 1993 16:32:23 +0200 Sender: Guido.van.Rossum@cwi.nl >From the responses so far I can conclude that having __init__ explicitly call the base class's __init__ is the best possible solution, so let's move on to Chris' suggestion: > By the way, will there be a __del__(self) method that is called at > destruction time? My thought on this was that when python sees that an > object should be garbage collected, it calls the object's __del__ > method (if any) before actually destroying it. Of course the > interpreter would have to check the object's refcount after calling > the function, as the method may have caused the object to be > referenced by some other object. The problem with this is, what to do if the __del__ call creates another reference to the object? You can't delete it then since the new reference would be dangling. But not deleting the object means that the __del__ method may be called again later when the reference count goes down to zero once again. Would this be a problem? > I don't really have a good example of why you'd want this, other than > for creating classes that keep track of how many instances of the > class exist. Perhaps someone else can think of a good reason for > having it. It just seems that if you have a function that is called at > object creation that you should have one that is called at object > destruction as well. Actually, there are lots of situations where a class is used as a wrapper around some "real-world" object (e.g. a window or a temporary file or an audio device) that you would want to destroy (or restore to a previous state) when the instance goes away. So yes, I think there are many cases where this would be useful. There's one problem with __del__, however: what if it raises an exception? __del__ will be called implicitly from a DECREF(x) statement in the C code, and I'm not going to add error checking to all DECREF() statements. So these exceptions will have to be ignored. In fact, there may already be an exception pending when DECREF() is called, so it may have to save and restore the original exception. Nasty! One final thing to ponder: if we have a __del__ method, should the interpreter guarantee that it is called when the program exits? (Like C++, which guarantees that destructors of global variables are called.) The only way to guarantee this is to go running around all modules and delete all their variables. But this means that __del__ method cannot trust that any global variables it might want to use still exist, since there is no way to know in what order variables are to be deleted. Or is this not a useful feature? --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> To: Chris Hoffmann <choffman@vicorp.com> cc: python-list Subject: Re: __init__ and __del__ In-reply-to: Your message of "Tue, 18 May 1993 09:56:07 MDT." <9305181356.AA20902@vicorp.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Tue, 18 May 1993 16:32:23 +0200 Sender: guido From the responses so far I can conclude that having __init__ explicitly call the base class's __init__ is the best possible solution, so let's move on to Chris' suggestion: > By the way, will there be a __del__(self) method that is called at > destruction time? My thought on this was that when python sees that an > object should be garbage collected, it calls the object's __del__ > method (if any) before actually destroying it. Of course the > interpreter would have to check the object's refcount after calling > the function, as the method may have caused the object to be > referenced by some other object. The problem with this is, what to do if the __del__ call creates another reference to the object? You can't delete it then since the new reference would be dangling. But not deleting the object means that the __del__ method may be called again later when the reference count goes down to zero once again. Would this be a problem? > I don't really have a good example of why you'd want this, other than > for creating classes that keep track of how many instances of the > class exist. Perhaps someone else can think of a good reason for > having it. It just seems that if you have a function that is called at > object creation that you should have one that is called at object > destruction as well. Actually, there are lots of situations where a class is used as a wrapper around some "real-world" object (e.g. a window or a temporary file or an audio device) that you would want to destroy (or restore to a previous state) when the instance goes away. So yes, I think there are many cases where this would be useful. There's one problem with __del__, however: what if it raises an exception? __del__ will be called implicitly from a DECREF(x) statement in the C code, and I'm not going to add error checking to all DECREF() statements. So these exceptions will have to be ignored. In fact, there may already be an exception pending when DECREF() is called, so it may have to save and restore the original exception. Nasty! One final thing to ponder: if we have a __del__ method, should the interpreter guarantee that it is called when the program exits? (Like C++, which guarantees that destructors of global variables are called.) The only way to guarantee this is to go running around all modules and delete all their variables. But this means that __del__ method cannot trust that any global variables it might want to use still exist, since there is no way to know in what order variables are to be deleted. Or is this not a useful feature? --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Tue, 18 May 1993 17:08:38 +0200 Replied: "dussud@lucid.com (Patrick Dussud) " Received: from aspen.lucid.com by charon.cwi.nl with SMTP id AA05009 (5.65b/3.8/CWI-Amsterdam); Tue, 18 May 1993 17:02:44 +0200 Received: by aspen.lucid.com (4.1/SMI-4.1) id AA18997; Tue, 18 May 93 08:02:38 PDT Date: Tue, 18 May 93 08:02:38 PDT From: dussud@lucid.com (Patrick Dussud) Message-Id: <9305181502.AA18997@aspen.lucid.com> To: Guido.van.Rossum@cwi.nl Cc: python-list@cwi.nl In-Reply-To: <9305172237.AA01454=guido@voorn.cwi.nl> (Guido.van.Rossum@cwi.nl) Subject: __init__ The Lisp community faced the same problem. Flavors and then CLOS adopted solution 1 with the convention that initialization values should be keyword arguments. They have the form <key> <value>. The original list is passed to all of the methods, which are free to pick the arguments they care about. I don't see how 1 can work without keyword argument, so I guess that 2 would be better in the context of Python. Patrick. Received: from att-out.att.com by charon.cwi.nl with SMTP id AA05576 (5.65b/3.8/CWI-Amsterdam); Tue, 18 May 1993 17:23:49 +0200 From: hzsbg01!jbuhrma@hvgtw.att.com Received: from hzsbc03 by hzsbg01 (4.1/SMI-4.1) id AA19630; Tue, 18 May 93 17:06:32 +0200 Date: Tue, 18 May 93 17:06:32 +0200 Original-From: hzsbg01!jbuhrma Message-Id: <9305181506.AA19630@hzsbg01> To: choffman@vicorp.com Subject: Re: __init__ Cc: python-list@cwi.nl > By the way, will there be a __del__(self) method that is called at > destruction time? [...] I don't really have a good example of why > you'd want this, other than for creating classes that keep track of > how many instances of the class exist. Perhaps someone else can think > of a good reason for having it. Look at the draw object in the stdwin module. When you delete the object, things get actually painted on screen. Up 'till now such a scheme is only possible with builtin objects. -- Jan-Hein Buhrman -- AT&T Huizen NL -- <jbuhrma%hzsbg01@hvlpa.att.com> -- ---------------------- +31 35 87.4278 --- ...!att!hvlpa!hzsbg01!jbuhrma --- ``When everything is bad, it must be good to know the worst'' --Francis Bradley, quoted on ``Who's Afraid of?... The Art of Noise!'' To: dussud@lucid.com (Patrick Dussud) Subject: Re: __init__ In-reply-to: Your message of "Tue, 18 May 1993 08:02:38 MDT." <9305181502.AA18997@aspen.lucid.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Tue, 18 May 1993 17:08:38 +0200 Sender: guido > The Lisp community faced the same problem. Flavors and then CLOS adopted > solution 1 with the convention that initialization values should be keyword > arguments. They have the form <key> <value>. The original list is passed to > all of the methods, which are free to pick the arguments they care about. I > don't see how 1 can work without keyword argument, so I guess that 2 would be > better in the context of Python. Are you sure you haven't reversed the options? My option 1 calls only the derived class' __init__ and leaves it up to that method to call the base class' __init__. My option 2 calls all base* class __init__ methods (buttom up) with the same argument list. This sounds like the reverse of what you're describing... --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from aspen.lucid.com by charon.cwi.nl with SMTP id AA07128 (5.65b/3.8/CWI-Amsterdam); Tue, 18 May 1993 18:09:36 +0200 Received: by aspen.lucid.com (4.1/SMI-4.1) id AA19117; Tue, 18 May 93 09:09:33 PDT Date: Tue, 18 May 93 09:09:33 PDT From: dussud@lucid.com (Patrick Dussud) Message-Id: <9305181609.AA19117@aspen.lucid.com> To: Guido.van.Rossum@cwi.nl In-Reply-To: <9305181508.AA05058=guido@voorn.cwi.nl> (Guido.van.Rossum@cwi.nl) Subject: __init__ From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Tue, 18 May 1993 17:08:38 +0200 Sender: Guido.van.Rossum@cwi.nl > The Lisp community faced the same problem. Flavors and then CLOS adopted > solution 1 with the convention that initialization values should be keyword > arguments. They have the form <key> <value>. The original list is passed to > all of the methods, which are free to pick the arguments they care about. I > don't see how 1 can work without keyword argument, so I guess that 2 would be > better in the context of Python. Are you sure you haven't reversed the options? My option 1 calls only the derived class' __init__ and leaves it up to that method to call the base class' __init__. My option 2 calls all base* class __init__ methods (buttom up) with the same argument list. This sounds like the reverse of what you're describing... --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Right you are. Patrick. Replied: Wed, 02 Jun 1993 13:19:53 +0200 Replied: "Doug Moen <dmoen@utcc.utoronto.ca> " Received: from gpu.utcc.utoronto.ca by charon.cwi.nl with SMTP id AA23130 (5.65b/3.8/CWI-Amsterdam); Fri, 28 May 1993 17:24:58 +0200 Received: by gpu.utcc.utoronto.ca id <18697>; Fri, 28 May 1993 11:24:41 -0400 From: Doug Moen <dmoen@utcc.utoronto.ca> To: python-list@cwi.nl Subject: replacing stdwin Message-Id: <93May28.112441edt.18697@gpu.utcc.utoronto.ca> Date: Fri, 28 May 1993 11:24:33 -0400 I am new to python, and new to python-list, so excuse me if this has been discussed before. I have been looking around for an industrial strength scripting and extension language to incorporate into a new product my company is developing, and I've pretty much settled on Python. The other thing we need is an industrial strength portable window system interface, with both C/C++ and Python bindings. Sadly, stdwin just doesn't cut it. So, I'm looking for alternatives. One possibility is to purchase a commercial platform-independent GUI library such as Aspect, C++/Views, Galaxy, Zinc, etc, and create a Python interface. Has anybody done this? Another possibility is to find a non-commercial GUI library (hopefully, one that is distributed on the same terms as Python), and create a Python interface to that. The advantage of this second approach is that the resulting package could be made freely distributable, and incorporated into the Python distribution. Any leads on this? Are there any "official" plans to replace stdwin with something better? P.S. Because we are developing a commercial product, we are committing significant manpower to fixing bugs, porting to new platforms*, creating a regression test suite, and adding enhancements. I would ideally like to fold these changes into the main Python distribution, so that we can benefit from the work that other Python developers are doing. By the way, just how much Python development activity is going on right now, and by how many people? When will version 1.0 be released? *New platforms: We are planning a 32 bit Microsoft Windows port, with dynamic loading implemented using DLLs. Probably this will force us to put the Python interpreter into a DLL. Has anyone done this before? Doug Moen dmoen@utcc.utoronto.ca To: Doug Moen <dmoen@utcc.utoronto.ca> Subject: Re: replacing stdwin In-reply-to: Your message of "Fri, 28 May 1993 11:24:33 MDT." <93May28.112441edt.18697@gpu.utcc.utoronto.ca> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Wed, 02 Jun 1993 13:19:53 +0200 Sender: guido Hi, I suppose you are less than impressed with the response to your mail... So am I. Here is what I know. > One possibility is to purchase a commercial platform-independent GUI library > such as Aspect, C++/Views, Galaxy, Zinc, etc, and create a Python interface. > Has anybody done this? Well, nobody has told me anybody about it if they did, so I very much doubt it. Have you thought of Interviews? It's in C++, but Python mixes reasonably well with that. Or what about XVT (a commercial stdwin-like package)? > Another possibility is to find a non-commercial GUI library (hopefully, one > that is distributed on the same terms as Python), and create a Python interface > to that. The advantage of this second approach is that the resulting package > could be made freely distributable, and incorporated into the Python > distribution. Any leads on this? Nothing, but a friend just pointed me to a public domain platform independent programming environment called wxwin, available for xview (OpenWindows), Motif and MS Windows. The only pointer I have is that someone found it at the University of Edinburgh... > Are there any "official" plans to replace stdwin with something better? The current trend in Python is towards Motif (see below), but that leaves the Mac and PC users rather in the cold... > Because we are developing a commercial product, we are committing significant > manpower to fixing bugs, porting to new platforms*, creating a regression > test suite, and adding enhancements. I would ideally like to fold these > changes into the main Python distribution, so that we can benefit from the > work that other Python developers are doing. Good idea! If you do make changes to the distribution, please don't reformat them -- context diffs relative to the latest release have the highest chances of being folded back. > By the way, just how much > Python development activity is going on right now, and by how many people? I know that several companies are considering Python as a scripting or extension language for one of their UNIX-based products. I don't know if they'd all let me mention their names though -- they are reading the list, so if they want to respond they can do so! Here are a few that I think are safe to mention: Sunrise Software have a version of their Motif GUI builder "ezX" which supports Python as one of the possible scripting languages. They've demonstrated this last year and I'm an official beta tester... V.I. Corporation have also invested quite some time in Python already, they are working on a very nice set of Motif bindings that they will release under similar conditions as the rest of Python. (While they were working on this, I did my own set of Motif bindings, which has somewhat less functionality but is much more robust so far. I hope I can prevent having two sets of incompatible bindings, so policy is to release nothing until this is resolved...) Several others are less far (or tell me less about what they are doing). There are also several companies who use Python for in-house projects like automated testing. Hope this helps... --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> PS: I'm sure I've seen your name on the net before but can't remember where or how. Quite possibly we've even exchanged mail log ago. You must be the author of some kind of famous software. Give me a clue...? Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA26844 (5.65b/3.8/CWI-Amsterdam); Fri, 4 Jun 1993 01:08:41 +0200 Received: by voorn.cwi.nl with SMTP id AA06557 (5.65b/3.8/CWI-Amsterdam); Fri, 4 Jun 1993 01:08:39 +0200 Message-Id: <9306032308.AA06557=guido@voorn.cwi.nl> To: python-list@cwi.nl Subject: DISCUSSION: Naming conventions (for C code) From: Guido.van.Rossum@cwi.nl X-Organization: CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Fri, 04 Jun 1993 01:08:39 +0200 Sender: Guido.van.Rossum@cwi.nl Naming Conventions -- A Draft Proposal ************************************** It is quite easy to extend Python with a new module written in C. It should be equally easy to embed the Python interpreter as a library in an existing (or new) application. This is indeed possible, but there is a potential problem when the application is large: the Python interpreter library defines many external names that may clash with names defined by the application. To a lesser extend the macros, structures and typedefs defined in Python's header files may also clash with application-defined names (or with names defined by other libraries, when the application needs to use several libraries in one file). This article proposes a change to the naming of all external functions, macros, structures, typedefs etc. that are in any way visible to the application with the intent to make clashes avoidable. (This excludes the names of static functions and variables, local variables, structure members, and macros, structures and typedefs defined in .c files.) At the same time the set of names is somewhat rationalized to make it easier to guess where a name is defined. The purpose of this proposal is to get feedback. This is your chance to make your voice heard! Please evaluate every aspect of the proposal and let me know whether you like it or not. No effort has yet begun to implement the proposal, so there are no big costs involved in changes to the proposal. Your opinion is especially important if you have written (or are maintaining) code that extends the Python interpreter, since you will have to change your code and learn to use the new conventions. Note that these changes affect the C code that implements the Python interpreter (and its extensions) only; the Python language as seen by Python programmers will remain unchanged! Basic Conventions ================= The mechanism to avoid clashes is to prefix all relevant names with the string Py. This gives an application a very simple way to avoid clashes: simply don't define names starting with Py in the application. A similar mechanism is successfully used by most widespread libraries, e.g. X. The full naming scheme gives functions a name as follows: Py<Module>_<Function>, where <Module> is the (sometimes abbreviated) name of the module to which the function belongs (this may also be a basic type), and <Function> is a descriptive name for the function. The <Module> and <Function> parts use a mixed-case convention: each is spelled with an initial capital letter, and if they consist of multiple words each word has an initial capital. Embedded underscores are not used except between <Module> and <Function>. Some examples: PyList_Append PyList_GetItem PyList_New PyString_GetValue PyErr_SetStr Functions applying to any kind of objects, and some other oft-used utility functions, have a prefix of just Py_, e.g. Py_Print Py_Repr Py_GetAttr Py_GetArg Py_MakeValue Global variables are named using similar conventions, e.g. PyType_List Py_ZeroDivisionError Functions and variables that have to be global for some reason but are not part of the official interface have an initial underscore, e.g. _Py_RefTotal Macros with arguments are named like functions, e.g.: Py_IsList Py_IncRef Macros without arguments (symbolic constants) have a second part that is entirely in capitals and uses underscores to separate words. So do enums. E.g.: Py_PRINT_RAW Typedefs contain no underscore; they consist of Py followed by one or more words with initial capitals, e.g.: PyObject PyListObject Most of these typedef names correspond to structures; the structure tag will be the typedef name prefixed with an underdscore. Note that the current system has a number of structures that are not covered by typedefs. These will be given typedef names. Also note that pointer types will continue to be written with the "*" notation, e.g. "PyObject *". Pointers in C have sufficiently special semantics to make it important in practice to know whether a particular variable is a pointer; e.g. Python frequently uses casts between various object pointers. Header files will follow the conventions for typedef names, e.g. "PyList.h" A header named "Python.h" will collect almost all useful headers. Transition Period ================= During a transition period, which will last at least two releases that each live at least 3 months (giving a total of at least 6 months), it will be possible to use the old names and the new names together. The transition mechanism uses #define to identify the new and old names. In the first transition release, the (majority of) source code will still use the old names, including the old header file names, but macros will be defined to support the use of the new names, e.g.: #define PyObject object In the second transition release, the source code will use the new names, also for header file names, and macros will be defined to support code that still uses the old names, e.g.: #define object PyObject Headers with the alternative names will be provided in both cases. In both transition releases, the compatibility macros will be gathered in a single header file (a different one each time!). A Python script will be provided which translates C code from the old to the new naming conventions with 99% accuracy. It remains to be seen whether occurrences in comments should be replaced; when comments refer to functions and typedefs etc., they should, but some names (e.g. object!) can also be used as a noun, so global substitutions may cause undesired effects. Also, there are some situations where names occurring in strings must be substituted! Other Changes ============= It may be possible to introduce other changes as well, e.g. changes to the source tree: I might separate the .h files from the .c files, separate optional modules from the required part of the interpreter, move the parser generator to its own directory. (Anything else?) Alternative Proposals ===================== A much simpler alternative would be to prefix all names with py_ (sometimes PY_) and leave everything else unchanged: py_object, py_getattr, py_is_listobject, etc. This will be easier for those (like myself!) whose eyes and fingers have been trained to use the current names, but it will leave the existing inconsistencies in place. (The Python language itself uses lowercase for must situations, but its library is not too consistent, so it cannot really serve as a guideline here.) --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from petunia.cwi.nl by charon.cwi.nl with SMTP id AA05525 (5.65b/3.8/CWI-Amsterdam); Fri, 4 Jun 1993 08:07:36 +0200 Received: by petunia.cwi.nl with SMTP id AA04902 (5.65b/3.8/CWI-Amsterdam); Fri, 4 Jun 1993 08:07:35 +0200 Message-Id: <9306040607.AA04902=ivan@petunia.cwi.nl> To: python-list@cwi.nl Subject: Re: DISCUSSION: Naming conventions (for C code) In-Reply-To: Your message of "Fri, 04 Jun 1993 01:08:39 MDT." <9306032308.AA06557=guido@voorn.cwi.nl> Date: Fri, 04 Jun 1993 08:07:34 +0200 From: Ivan Herman <Ivan.Herman@cwi.nl> I totally agree with the necessity of a consistent naming convention; being in the process in embedding the interpreter into a C++ program, we clearly feel the necessity. Your proposal seems to be o.k. to me; in fact, I do not think a long discussion is necessary. So: go for it! Ivan Received: from gpu.utcc.utoronto.ca by charon.cwi.nl with SMTP id AA05753 (5.65b/3.8/CWI-Amsterdam); Fri, 4 Jun 1993 08:16:47 +0200 Received: by gpu.utcc.utoronto.ca id <18711>; Fri, 4 Jun 1993 02:16:39 -0400 From: Doug Moen <dmoen@utcc.utoronto.ca> To: python-list@cwi.nl Subject: Re: DISCUSSION: Naming conventions (for C code) Message-Id: <93Jun4.021639edt.18711@gpu.utcc.utoronto.ca> Date: Fri, 4 Jun 1993 02:16:29 -0400 I approve of the proposed new consistent naming convention. The programming convention we use suffixes all typedef names with "_t"; thus, struct PyObject { ... } PyObject_t. The _t convention has the advantage of being instantly understood by all C programmers (because of size_t, etc, in the ANSI C standard). I'm not so happy about the alternative suggestion of just prefixing the existing names with py_, since this "will leave the existing inconsistencies in place". Python has a great future ahead of it; a little work at fixing inconsistencies now will repay itself with interest. Future generations will praise your foresight (just as they curse the designers of C for not fixing the gets/fgets botch in the mid seventies, to avoid inconveniencing a few dozen people). The directory reorganization (putting different kinds of files into different directories) will be a big win for us, since it will make it much easier for us to build python using the Qef construction tool (we don't use make). When you rename the header files, please don't exceed 8 characters before the ".h"; this will make it easier for me when I compile the DOS and Windows versions of Python. You mention a python script for automating the name change. Here is how we do name changes of this sort at my organization. 1. First, we use a grep variant which takes a list of C identifiers rather than a regular expression, and produce a file of the form filename:lineno:contents of file ... This is the same format that grep outputs. 2. Then, we visually scan the file, looking for lines that shouldn't actually be changed (eg, comment lines containing the word "object" in the English sense); these lines are deleted. 3. Then, we perform a global substitution on the file. We use a tool which takes a dictionary of old-C-identifier, new-C-identifier pairs, one pair per line, separated by tabs. 4. A final visual scan, to make sure no mistaken substitutions were made. 5. Finally, we feed the file to a tool called "repl", which interprets the filename and lineno fields, and replaces the indicated lines in the indicated files with the new text. With the above procedure, large scale name changes are fairly easy to do. The nice thing about this procedure is that it's quick and easy to eyeball the changes before you commit to them. Received: from alpha.Xerox.COM by charon.cwi.nl with SMTP id AA12564 (5.65b/3.8/CWI-Amsterdam); Fri, 4 Jun 1993 10:54:14 +0200 Received: from eros.EuroPARC.Xerox.COM ([13.1.252.143]) by alpha.xerox.com with SMTP id <11582>; Fri, 4 Jun 1993 01:53:57 PDT Received: by eros.EuroPARC.Xerox.COM with SMTP (5.65c/IDA-1.2.9) id AA19888; Fri, 4 Jun 1993 09:53:36 +0100 Message-Id: <199306040853.AA19888@eros.EuroPARC.Xerox.COM> To: Guido.van.Rossum@cwi.nl Subject: Re: DISCUSSION: Naming conventions (for C code) In-Reply-To: Your message of "Thu, 03 Jun 93 16:08:39 PDT." <9306032308.AA06557=guido@voorn.cwi.nl> Date: Fri, 4 Jun 1993 01:53:35 PDT From: Fraser@europarc.xerox.com Guido - The proposals seem very sensible to me. I have just a couple of modules which would need adjusting, but that would be 10 minutes' work. I am planning to try embedding the interpreter in a Modula-3 program in the near future (because it seems like a much happier marriage than, say, M3 & Tcl) and this could be a great help. I hope it's not too much work for you, though! Quentin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Quentin Stafford-Fraser Rank Xerox EuroPARC, Oh, what a tangled web we weave, Cambridge, UK When first we practise to deceive Tel: +44 223 341529 But when we've practised quite a while Fax: +44 223 341510 How vastly we improve our style! Fraser@europarc.xerox.com Received: from schelvis.cwi.nl by charon.cwi.nl with SMTP id AA16333 (5.65b/3.8/CWI-Amsterdam); Fri, 4 Jun 1993 12:56:17 +0200 Received: by schelvis.cwi.nl with SMTP id AA07505 (5.65b/3.8/CWI-Amsterdam); Fri, 4 Jun 1993 12:56:16 +0200 Message-Id: <9306041056.AA07505=jack@schelvis.cwi.nl> To: python-list@cwi.nl Subject: Re: DISCUSSION: Naming conventions (for C code) Organisation: Multi-media group, CWI, Kruislaan 413, Amsterdam Phone: +31 20 5924098(work), +31 20 5924199 (fax), +31 20 6160335(home) X-Last-Band-Seen: NO FX (Melkweg, 1-6) X-Mini-Review: Great! Date: Fri, 04 Jun 1993 12:56:15 +0200 From: Jack Jansen <Jack.Jansen@cwi.nl> Sounds like a good idea. -- Jack Jansen | If I can't dance I don't want to be part of Jack.Jansen@cwi.nl | your revolution -- Emma Goldman uunet!cwi.nl!jack G=Jack;S=Jansen;O=cwi;PRMD=surf;ADMD=400net;C=nl Received: from inesc.inesc.pt by charon.cwi.nl with SMTP id AA18405 (5.65b/3.8/CWI-Amsterdam); Fri, 4 Jun 1993 14:06:41 +0200 Received: from flausina.inesc.pt by inesc.inesc.pt with SMTP; id AA10707 (5.65c/SunOS4.1.3); Fri, 4 Jun 1993 14:05:27 +0200 Received: by flausina.inesc.pt (4.1/SunOS4.1.1) id AA14177; Fri, 4 Jun 93 14:06:51 +0200 Date: Fri, 4 Jun 93 14:06:51 +0200 From: pereira@flausina.inesc.pt (Jose Pereira) Message-Id: <9306041206.AA14177@flausina.inesc.pt> To: Guido.van.Rossum@cwi.nl Cc: python-list@cwi.nl Subject: DISCUSSION: Naming conventions (for C code) In-Reply-To: <9306032308.AA06557=guido@voorn.cwi.nl> References: <9306032308.AA06557=guido@voorn.cwi.nl> It sounds a Good & Sensible Thing. I would only make a suggestion: Instead of: > Global variables are named using similar conventions, e.g. > > PyType_List > Py_ZeroDivisionError I would say: PyType_list Py_zeroDivisionError That is, to make a distinction between function names and variables by starting these with a lower case letter. It's not that important, but helps a little when you are using a debugger and want a quick visual check of a particular global name. -- ---------------------------------------------------------------------- Jose' Pereira INESC (Inst. Eng. Sistemas e Computadores) R. Alves Redol 9, 6. 1000 Lisboa, PORTUGAL. Phone.: +351 1 3100225 Fax...: +351 1 525843 e-mail: jmp@inesc.pt PSI...: %(0268)004010314::inesc::jmp Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA24529 (5.65b/3.8/CWI-Amsterdam); Fri, 4 Jun 1993 17:07:56 +0200 From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: Guido.van.Rossum@cwi.nl Subject: Re: DISCUSSION: Naming conventions (for C code) Cc: python-list@cwi.nl Date: Fri, 4 Jun 93 8:06:50 PDT Message-Id: <9306040806.aa29166@hermix.markv.com> >Global variables are named using similar conventions, e.g. > >PyType_List >Py_ZeroDivisionError I think that variables should have the first letter after the underscore in lowercase to distinguise them from functions... >Typedefs contain no underscore; they consist of Py followed by one or >more words with initial capitals, e.g.: > >PyObject >PyListObject I like having something like PyObject_t. This will make it easier to look into the code and see if it is a typedef. It is also more standard since most of ANSI typedefs are like that.. >Also note that pointer types will continue to be written with the "*" >notation, e.g. "PyObject *". Pointers in C have sufficiently special >semantics to make it important in practice to know whether a >particular variable is a pointer; e.g. Python frequently uses casts >between various object pointers. I don't like this.. I like the following.. typedef struct _PyObject { .... } PyObject_t, *pPyObject_t, **ppPyObject_t; Or typedef struct _PyObject { .... } PyObject_t, *PyObjectP_t, **PyObjectPP_t; This makes the code a little cleaner to read and makes it harder to miss putting in a '*'. >Other Changes >============= > >It may be possible to introduce other changes as well, e.g. changes to >the source tree: I might separate the .h files from the .c files, >separate optional modules from the required part of the interpreter, >move the parser generator to its own directory. (Anything else?) Yes.. I would like to see it layed out like this for the source tree... python/src/ python/src/h/ python/src/lib/modules/ python/src/lib/objects/ python/src/lib/parser/ python/src/lib/h/ python/src/optional/ python/src/optional/package_name/ python/lib/ /* This is where the libpython.a file gets put */ python/include/ /* each makefile when given the "install" flag puts */ /* "external" header files here */ python/bin/ /* This is where the executables gets put */ python/doc/ python/samples/ python/support/lib/ /* This is what the current 'lib' directory would become */ Each of the directories in src/lib/* and src/optional/* would have it's own makefile. Thre would be a toplevel makefile in src that would call each of the other makefiles... just my ideas... Lance Ellinghouse lance@markv.com Received: from newton.ncsa.uiuc.edu by charon.cwi.nl with SMTP id AA25501 (5.65b/3.8/CWI-Amsterdam); Fri, 4 Jun 1993 17:34:22 +0200 Received: from void.ncsa.uiuc.edu by newton.ncsa.uiuc.edu with SMTP id AA16386 (5.65a/IDA-1.4.2 for Guido.van.Rossum@cwi.nl); Fri, 4 Jun 93 10:34:19 -0500 Return-Path: <liberte@ncsa.uiuc.edu> Received: by void.ncsa.uiuc.edu (4.1/NCSA-4.1) id AA04350; Fri, 4 Jun 93 10:33:47 CDT Date: Fri, 4 Jun 93 10:33:47 CDT From: liberte@ncsa.uiuc.edu (Daniel LaLiberte) Message-Id: <9306041533.AA04350@void.ncsa.uiuc.edu> To: Guido.van.Rossum@cwi.nl Subject: Re: DISCUSSION: Naming conventions (for C code) I agree you need to prefix C extern names with some code to protect names. Without this protection, name clashes can be very difficult and cumbersome to get around. dan Replied: Sat, 05 Jun 1993 00:24:45 +0200 Replied: "Donald Beaudry <don@vicorp.com> " Received: from relay1.UU.NET by charon.cwi.nl with SMTP id AA26048 (5.65b/3.8/CWI-Amsterdam); Fri, 4 Jun 1993 17:53:15 +0200 Received: from vicorp.com (via vicorp.vicorp.com) by relay1.UU.NET with SMTP (5.61/UUNET-internet-primary) id AA13056; Fri, 4 Jun 93 11:53:24 -0400 Received: from zippy.vicorp.com by vicorp.com (4.1/SMI-4.1) id AA04729; Fri, 4 Jun 93 11:51:31 EDT Date: Fri, 4 Jun 93 11:51:31 EDT From: Donald Beaudry <don@vicorp.com> Message-Id: <9306041551.AA04729@vicorp.com> To: Guido.van.Rossum@cwi.nl Cc: python-list@cwi.nl In-Reply-To: Guido.van.Rossum@cwi.nl's message of Fri, 04 Jun 1993 01:08:39 +0200 <9306032308.AA06557=guido@voorn.cwi.nl> Subject: DISCUSSION: Naming conventions (for C code) What a great idea! > The full naming scheme gives functions a name as follows: > Py<Module>_<Function>, where <Module> is the (sometimes abbreviated) > name of the module to which the function belongs (this may also be a > basic type), and <Function> is a descriptive name for the function. > The <Module> and <Function> parts use a mixed-case convention: each > is spelled with an initial capital letter, and if they consist of > multiple words each word has an initial capital. Embedded underscores > are not used except between <Module> and <Function>. Some examples: > PyList_Append > PyList_GetItem > PyList_New > PyString_GetValue > PyErr_SetStr This is fine for all of the built in objects types but I would like to suggest a slight variation for use with extension modules. Each extension module should have a short abbreviation which is then inserted between the Py and the object name. Using this convention will allow one extention module to define objects with the same as another extention module with out having to worry name collisions. For example, Motif defines a string type which when wrapped by a Python object should be called PyXmString. Any other objects added by the Xm module should be name in a similar manner, PyXmFontList is another example. > Global variables are named using similar conventions, e.g. > PyType_List > Py_ZeroDivisionError I suppose that we have to have a naming convention for global variables though I believe that their use should be strongly discouraged. Often they are unavoidable and in these cases they should not be part of the public interface to the module in which they are declared. Rather, they should be named with a leading underscore to indicate that they are private to the module and the module should provide a procedural interface to them. If performance is crucial then this interface could take the form for a macro or two. > Functions and variables that have to be global for some reason but are > not part of the official interface have an initial underscore, e.g. > _Py_RefTotal This rule should also apply to any name that is not part of the official interface. Often it is useful to define structure or macros that need to be shared by the files of a module, but are of no use to the user of the module. > Macros with arguments are named like functions, e.g.: > Py_IsList > Py_IncRef I think that the distinction here should not be based on the existance of arguments, but on the usage of the arguments. If the macro acts like, and can be replaced by a function then it should be named like a function. This is an important distinction since some macros are not very well behaved and evaluate their arguments more than once, or they do what cannot be done by a function, like statically initialize a structure (OB_HEAD). These non-function macros should be named entirely in capitals with underscores seperating the words. > Note that the current system has a number of structures that are not > covered by typedefs. These will be given typedef names. Good. > Also note that pointer types will continue to be written with the "*" > notation, e.g. "PyObject *". Pointers in C have sufficiently special > semantics to make it important in practice to know whether a > particular variable is a pointer; e.g. Python frequently uses casts > between various object pointers. Using this conventions will make it less convienent to use a very useful information hiding trick. Often, the definition of a structure only needs to be known within the module that uses it. The public header file can then declare a typedef as a pointer to the structure without specifying the structure at all. Using this convention will either force all structure defination to be exposed in the public header files. I think that a better approach is to define all stuctures with a typedef name that ends with the suffix 'Struct', (or 'Rec' as Xt does). And then use a typedef to create a pointer type for that structure. The name should be the same as the structure minus the suffix. Now, header files can declare the same pointer type without having access to the actual structure definition. It is true that this hides the fact the the type is a pointer, but whenever the type is used outside of the module of its defination, only the public interface functions should be used to access the type, thus the question of whether or not it is a pointer becomes irrelevant. > Header files will follow the conventions for typedef names, e.g. > "PyList.h" I would rather see header files put into a seperate directory, for a couple of reasons. First, it helps to keep the name of the header file short. On many systems, this is very important. And second, it makes it possible to distinguish public header file from private header files. That is, only public header files will be moved (linked, copied, whatever) into the public area. All private headers could be kept with the source that needs them. So, include directives would end up looking somthing like this: #include <Py/List.h> #include <PyXt/Widget.h> #include <PyXm/String.h> > A header named "Python.h" will collect almost all useful headers. When it comes to header file inclusion, I have a simple rule that I like to follow: "If you use it, include it." In other words, if your source uses any of the functionality or types provided by a header file it should explicitly include that header file. This rule also applies to header files that use types defined in other header files. Also, you should not assume that a given header file includes any other header file for you. This implies that all header files should guard against multiple inclusion by wrappign themselves in a preprocessor directive like this. #ifndef PyHEADER_FILE_H #define PyHEADER_FILE_H <text of header file> #endif Unnecessary inclusion of header files lead to unnecessary dependencies. And unnecessary dependencies lead to unnecessary compilation. Unnecessary compliations lead to unnecessarily long compilation times. And I hate unnecessarily long compile times. > It may be possible to introduce other changes as well, e.g. changes to > the source tree: I might separate the .h files from the .c files, > separate optional modules from the required part of the interpreter, > move the parser generator to its own directory. (Anything else?) The seperation of optional from the required would be great. I would also like to see this as an opportunity to remove many of the abbreviation currently in use. Sure abbreviation are easy to type but I find them difficult to read. If used at all, I would only like to see them on the left hand side of the underscore (assuming the naming scheme described in the proposal) and only when that part of the name starts to get obnoxishly long. --Don ______ ______ \_\_\_\ /#/#/#/ \_\_\_\ ______ \_\_\_V#/#/#/ Donald Beaudry don@vicorp.com \_\_/#/#/#/ V. I. Corporation uunet!vicorp!don \_/#/#/#/ 47 Pleasant Street PHONE: (413) 586-4144 V#/#/#/ Northampton, MA 01060 FAX: (413) 586-3805 Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA26421 (5.65b/3.8/CWI-Amsterdam); Fri, 4 Jun 1993 18:02:44 +0200 Received: from eng2.sequent.com by gateway.sequent.com (5.61/1.34) id AA01611; Fri, 4 Jun 93 09:04:14 -0700 Received: by eng2.sequent.com (5.65/1.34) id AA13404; Fri, 4 Jun 93 09:02:30 -0700 Message-Id: <9306041602.AA13404@eng2.sequent.com> To: lance@markv.com Cc: Guido.van.Rossum@cwi.nl, python-list@cwi.nl Subject: Re: DISCUSSION: Naming conventions (for C code) Priority: Normal Precedence: first-class Organization: Sequent Computer Systems, Inc. Service Technology - MailStop: WIL2-610 15450 S.W. Koll Parkway Beaverton, OR 97006-6063 X-Phone: (503) 578-4404 X-Fax: (503) 578-4540 X-Uucp: ...!uunet!sequent!jaap X-Internet: jaap@sequent.com X-Face: C4Cnai$>Eja5I6Vq?(gdN#SXX#`-XgAnmUn&e54sx7@1>q@vkrd_XnH![P>w.:7IJJ;{Bts WJd)u&G!V}0OR?2o5cUgIY}.T{g]PMC=*~]3n_t)S-ZkC(WG}3:#hcA6Oazx:}yc&k,hsF7D},7x>l nyfRjO7$@]fHBN>aC9-M3pKfbYHiy!PWD{_bx~fo})b4tU.;Ao%x[upCI, In-Reply-To: Lance Ellinghouse's message of Fri, 04 Jun 1993 08:06:50 -0700. <9306040806.aa29166@hermix.markv.com> Date: Fri, 04 Jun 1993 09:02:29 -0700 From: Jaap Vermeulen <jaap@sequent.com> I agree with Lance and Jose. Except... :-) | Yes.. I would like to see it layed out like this for the source tree... | ... | python/lib/ /* This is where the libpython.a file gets put */ | python/include/ /* each makefile when given the "install" flag puts */ | /* "external" header files here */ | python/bin/ /* This is where the executables gets put */ | python/doc/ | python/samples/ | python/support/lib/ /* This is what the current 'lib' directory would become */ Here I disagree. The python libraries are true libraries and should be treated as such. Therefore, they should be placed in 'python/lib/python' IMO. This would follow the same conventions as '/usr' or '/usr/local'. (Picky, picky). -Jaap- -- Jaap Vermeulen +--------------------------+ | Sequent Computer Systems | Internet : jaap@sequent.com | Beaverton, Oregon | Uucp : ...uunet!sequent!jaap +--------------------------+ Received: from relay2.UU.NET by charon.cwi.nl with SMTP id AA27697 (5.65b/3.8/CWI-Amsterdam); Fri, 4 Jun 1993 18:46:10 +0200 Received: from spool.uu.net (via LOCALHOST) by relay2.UU.NET with SMTP (5.61/UUNET-internet-primary) id AA01083; Fri, 4 Jun 93 12:46:24 -0400 Received: from island.UUCP by spool.uu.net with UUCP/RMAIL (queueing-rmail) id 124626.29833; Fri, 4 Jun 1993 12:46:26 EDT Received: from bali.island.com by island.COM (4.1/SMI-4.1) id AA03610; Fri, 4 Jun 93 09:20:41 PDT Received: by bali.island.com (4.1/SMI-4.1) id AA02422; Fri, 4 Jun 93 09:20:50 PDT Date: Fri, 4 Jun 93 09:20:50 PDT From: erik@bali.island.COM (Erik de Bueger) Message-Id: <9306041620.AA02422@bali.island.com> To: Guido.van.Rossum@cwi.nl Subject: Re: DISCUSSION: Naming conventions (for C code) Good Idea! We are planning on incorporating python in our applications, and this will avoid name clashes for sure (names like 'object' are very much likely to be used elsewhere). Your proposal about the naming sounds fine to me. Erik de Bueger Island Graphics Corporation Replied: Sat, 05 Jun 1993 00:06:46 +0200 Replied: "Gerry Stringer <gerry@camscan.co.uk> " Received: from eros.uknet.ac.uk by charon.cwi.nl with SMTP id AA02432 (5.65b/3.8/CWI-Amsterdam); Fri, 4 Jun 1993 20:29:35 +0200 Received: from camscan.co.uk by eros.uknet.ac.uk with UUCP id <sg.13109-0@eros.uknet.ac.uk>; Fri, 4 Jun 1993 19:29:32 +0100 Received: from electra.camscan.co.uk by star.camscan.co.uk; Fri, 4 Jun 93 19:24:26 BST From: Gerry Stringer <gerry@camscan.co.uk> Date: Fri, 4 Jun 93 19:24:30 BST Message-Id: <21038.9306041824@electra.camscan.co.uk> To: python-list@cwi.nl Subject: pyhon & C++ There's been a sudden little flareup of mail on this list so I thought I might share some progress and raise a few small questions. Overview: We've reached the stage in our project where we need an interpreter front end (ddoesn't everyone) for user scripting/ customisation. I'm also getting a little disenchanted with the speed of C++ compilation so I'm looking for the possibility of the interpreter being used as a replacement for some C++. Python seemed the obvious choice to fit the bill because: 1. there's a good chance a punter,I mean customer, could understand the syntax ie. not too hieroglyphic with lots of braces etc. 2. there's a reasonable match between Python and C++ Pythongen: We've got the classic problem of interfacing to lots of existing code (about 400,000 lines of code and headers) hence the obvious move of writing a 'stub generator' which, given a much cut down class description can generate all the necessary code to be able to call the class methods from python. We've done this by writing a utility called pythongen. eg. given a file "PSessionApplication.pgen" containing: #include "../PSessionApplication/PSessionApplication.h" #include "../session.h" #include "String.h" class PSessionApplication ; Constructor = {|<CONSPTR>| = sessionapp ;}; void savetoDB(String asname) ; void startprog(char* ptypename,int nargs,char* [nargs]) ; String get_save_name() ; After running pythongen on the file and the usual compilation tedium I can do import PSessionApplication session.startprog('someprogram',3,['-Wp','527','157']) this is I actuallly Replied: Sat, 05 Jun 1993 00:03:08 +0200 Replied: "Lance Ellinghouse <lance@markv.com> python-list" Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA05288 (5.65b/3.8/CWI-Amsterdam); Fri, 4 Jun 1993 21:29:16 +0200 From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: python-list@cwi.nl Subject: unix signal() handeling... Date: Fri, 4 Jun 93 12:28:48 PDT Message-Id: <9306041228.aa23487@hermix.markv.com> Has anyone created a set of routines to attach arbitrary signal handlers to signals from inside Python? What I would like to be able to do is catch signals inside python and then call python code to handle the signals. Lance Ellinghouse lance@markv.com Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA10137 (5.65b/3.8/CWI-Amsterdam); Sat, 5 Jun 1993 00:03:11 +0200 Received: by voorn.cwi.nl with SMTP id AA09070 (5.65b/3.8/CWI-Amsterdam); Sat, 5 Jun 1993 00:03:08 +0200 Message-Id: <9306042203.AA09070=guido@voorn.cwi.nl> To: Lance Ellinghouse <lance@markv.com> Cc: python-list@cwi.nl Subject: Re: unix signal() handeling... In-Reply-To: Your message of "Fri, 04 Jun 1993 12:28:48 MDT." <9306041228.aa23487@hermix.markv.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Sat, 05 Jun 1993 00:03:08 +0200 Sender: Guido.van.Rossum@cwi.nl > Has anyone created a set of routines to attach arbitrary signal > handlers to signals from inside Python? > > What I would like to be able to do is catch signals inside python > and then call python code to handle the signals. I haven't heard of anyone trying it yet. Can you give an example of how this would be useful? In any case you would have to handle them in a similar way as the KeyboardInterrupt exception is currently handled: the real (C) signal handler only sets a flag that the signal has arrived, and then later the interpreter checks this flag (possibly after each (virtual) instruction -- currently it's done only every few instructions) and invokes the code that handles the signal. I suppose you could set it up so that if the handler returns the interpreter continues where it left off, while if the handler raises an exception the interpreter passes the exception on. KeyboardInterrupt could then be made a special case of this. Note that you won't be able to catch program bugs in the Python interpreter this way (since they must be handled synchronously). There is also the problem that not all wrappers around blocking system calls (or blocking library calls) will will yield return when a signal handler is called, so the Python signal handling may wait until the call returns normally -- this is usually not what you want. I'm sorry... --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> To: Lance Ellinghouse <lance@markv.com> cc: python-list Subject: Re: unix signal() handeling... In-reply-to: Your message of "Fri, 04 Jun 1993 12:28:48 MDT." <9306041228.aa23487@hermix.markv.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Sat, 05 Jun 1993 00:03:08 +0200 Sender: guido > Has anyone created a set of routines to attach arbitrary signal > handlers to signals from inside Python? > > What I would like to be able to do is catch signals inside python > and then call python code to handle the signals. I haven't heard of anyone trying it yet. Can you give an example of how this would be useful? In any case you would have to handle them in a similar way as the KeyboardInterrupt exception is currently handled: the real (C) signal handler only sets a flag that the signal has arrived, and then later the interpreter checks this flag (possibly after each (virtual) instruction -- currently it's done only every few instructions) and invokes the code that handles the signal. I suppose you could set it up so that if the handler returns the interpreter continues where it left off, while if the handler raises an exception the interpreter passes the exception on. KeyboardInterrupt could then be made a special case of this. Note that you won't be able to catch program bugs in the Python interpreter this way (since they must be handled synchronously). There is also the problem that not all wrappers around blocking system calls (or blocking library calls) will will yield return when a signal handler is called, so the Python signal handling may wait until the call returns normally -- this is usually not what you want. I'm sorry... --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> To: Donald Beaudry <don@vicorp.com> Subject: Re: DISCUSSION: Naming conventions (for C code) In-reply-to: Your message of "Fri, 04 Jun 1993 11:51:31 MDT." <9306041551.AA04729@vicorp.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Sat, 05 Jun 1993 00:24:45 +0200 Sender: guido You say many wise words. Just one thing right now on an issue where I won't give up easily... > Using this conventions will make it less convienent to use a very > useful information hiding trick. Often, the definition of a structure > only needs to be known within the module that uses it. The public > header file can then declare a typedef as a pointer to the structure > without specifying the structure at all. Using this convention will > either force all structure defination to be exposed in the public ^^^^^^ > header files. Actually, it is completely legal in C (even pre-ANSI C!) to do things like struct unknown_tag *p; /* pointer to unknown structure */ and typedef struct unknown_tag opaque_t; /* opaque typedef */ where "struct unknown_tag" is not defined in the current file. The latter makes it possible to declare pointers to opaque_t objects but not to declare opaque_t objects (then the compiler will say "unknown size" or so). As a compromise I can see defining both, say, PyObject and PyObjectPtr, so I can write "PyObject *p" and you can write "PyObjectPtr p". I can read the latter style but prefer to write the former; I suppose for you it's the other way around :-) (I'm still waiting for the "or" part of your last sentence here...) --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Sat, 05 Jun 1993 10:33:05 +0200 Replied: "Lance Ellinghouse <lance@markv.com> " Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA17568 (5.65b/3.8/CWI-Amsterdam); Sat, 5 Jun 1993 01:55:28 +0200 From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: Guido.van.Rossum@cwi.nl Subject: Re: unix signal() handeling... Cc: python-list@cwi.nl Date: Fri, 4 Jun 93 16:55:06 PDT Message-Id: <9306041655.aa15016@hermix.markv.com> >> Has anyone created a set of routines to attach arbitrary signal >> handlers to signals from inside Python? >> >> What I would like to be able to do is catch signals inside python >> and then call python code to handle the signals. > >I haven't heard of anyone trying it yet. Can you give an example of >how this would be useful? Ok.. For my example.. I have a single program that manages ~40 other programs. One thing I would like to do is be able to set a signal handler so that it would catch SIGCLD and then run another instance of the program that quit. This is easy to do in the C code, BUT I don't want to! I want it to be 100% changable in Python code (thus more flexible). I COULD poll each process with posix.kill(0,pid) but I really prefer NOT to have to poll.. This program will be doing enough keeping up with all the processing it has to do on the side.. Another instance would be to catch SIGHUP so that you could monitor a modem line and have Python code deal with a person hanging up on the line.. >In any case you would have to handle them in a similar way as the >KeyboardInterrupt exception is currently handled: the real (C) signal >handler only sets a flag that the signal has arrived, and then later >the interpreter checks this flag (possibly after each (virtual) >instruction -- currently it's done only every few instructions) and >invokes the code that handles the signal. I suppose you could set it >up so that if the handler returns the interpreter continues where it >left off, while if the handler raises an exception the interpreter >passes the exception on. KeyboardInterrupt could then be made a >special case of this. This sounds reasonable.. I would be happy to code it.. (signal handling) Where should I start looking? >Note that you won't be able to catch program bugs in the Python >interpreter this way (since they must be handled synchronously). Not wanting to.. >There is also the problem that not all wrappers around blocking system >calls (or blocking library calls) will will yield return when a signal >handler is called, so the Python signal handling may wait until the >call returns normally -- this is usually not what you want. This should be ok in most cases.. at least the ones I am dealing with Lance Ellinghouse lance@markv.com Replied: Sat, 05 Jun 1993 10:36:18 +0200 Replied: "Jaap Vermeulen <jaap@sequent.com> " Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA20122 (5.65b/3.8/CWI-Amsterdam); Sat, 5 Jun 1993 02:24:47 +0200 Received: from eng2.sequent.com by gateway.sequent.com (5.61/1.34) id AA19269; Fri, 4 Jun 93 17:26:21 -0700 Received: by eng2.sequent.com (5.65/1.34) id AA22703; Fri, 4 Jun 93 17:24:39 -0700 Message-Id: <9306050024.AA22703@eng2.sequent.com> To: lance@markv.com Cc: Guido.van.Rossum@cwi.nl, python-list@cwi.nl Subject: Re: unix signal() handeling... Priority: Normal Precedence: first-class Organization: Sequent Computer Systems, Inc. Service Technology - MailStop: WIL2-610 15450 S.W. Koll Parkway Beaverton, OR 97006-6063 X-Phone: (503) 578-4404 X-Fax: (503) 578-4540 X-Uucp: ...!uunet!sequent!jaap X-Internet: jaap@sequent.com X-Face: C4Cnai$>Eja5I6Vq?(gdN#SXX#`-XgAnmUn&e54sx7@1>q@vkrd_XnH![P>w.:7IJJ;{Bts WJd)u&G!V}0OR?2o5cUgIY}.T{g]PMC=*~]3n_t)S-ZkC(WG}3:#hcA6Oazx:}yc&k,hsF7D},7x>l nyfRjO7$@]fHBN>aC9-M3pKfbYHiy!PWD{_bx~fo})b4tU.;Ao%x[upCI, In-Reply-To: Lance Ellinghouse's message of Fri, 04 Jun 1993 16:55:06 -0700. <9306041655.aa15016@hermix.markv.com> Date: Fri, 04 Jun 1993 17:24:38 -0700 From: Jaap Vermeulen <jaap@sequent.com> | Ok.. For my example.. I have a single program that manages | ~40 other programs. One thing I would like to do is be able to set I had to deal with ~200 to ~400 processes that I would keep going all the time. I would just do a wait, see which processes exited and restart it. The code would something look like: ... pid = posix.fork() if pid: processes[`pid`] = ... else: ... ... pid, exitcode = posix.wait() ... = processes[`pid`] What I did in the '...' is that I had a object that would manage a process. You could start a process with arguments etc., or you could restart (it would remember the arguments), or you wait for it specifically, or you could kill it etc. Good luck, -Jaap- -- Jaap Vermeulen +--------------------------+ | Sequent Computer Systems | Internet : jaap@sequent.com | Beaverton, Oregon | Uucp : ...uunet!sequent!jaap +--------------------------+ Replied: Wed, 16 Jun 1993 10:22:09 +0200 Replied: "Lance Ellinghouse <lance@markv.com> " Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA14630 (5.65b/3.8/CWI-Amsterdam); Wed, 16 Jun 1993 03:03:12 +0200 From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: python-list@cwi.nl Subject: incorrect prototypes?? Date: Tue, 15 Jun 93 18:02:38 PDT Message-Id: <9306151802.aa23797@hermix.markv.com> Is there a reason that things like getlistsize() take a 'object *' instead of a 'listobject *' ???? This does not make much sense... Can this be added to the "Clean Up List"??? Lance Ellinghouse lance@markv.com Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA00357 (5.65b/3.8/CWI-Amsterdam); Wed, 16 Jun 1993 12:47:40 +0200 Received: by voorn.cwi.nl with SMTP id AA16382 (5.65b/3.8/CWI-Amsterdam); Wed, 16 Jun 1993 12:47:40 +0200 Message-Id: <9306161047.AA16382=guido@voorn.cwi.nl> To: python-list@cwi.nl Subject: Re: incorrect prototypes?? In-Reply-To: Your message of "Tue, 15 Jun 1993 18:02:38 MDT." <9306151802.aa23797@hermix.markv.com> X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Wed, 16 Jun 1993 12:47:40 +0200 From: Guido van Rossum <Guido.van.Rossum@cwi.nl> > Is there a reason that things like getlistsize() take > a 'object *' instead of a 'listobject *' ???? > > This does not make much sense... This was done on purpose, because in many cases one has received an "object*" (e.g. as an argument), detects that it is a list by using "is_listobject()", and then wants to access it as a list. If all the list-specific functions took a "listobject*" as argument, one would either have to copy the object into a local variable of that type, or use a cast on each call. I am not very fond of casts (since the compiler will happily cast e.g. a "char*" to "listobject*") so I prefer to minimize their number. It's true that now there's a cast inside listgetsize(), but that's one cast per function definition instead of one cast per function call. Also note that getlistsize() tests its argument for list-ness. Strictly spoken this should be redundant, but many people (including me!) sometimes write sloppy code that doesn't always check the types of objects passing through a function. The function err_badcall() (used in such occasions) currently raises an exception, but can easily be changed to call abort(), which pin-points the cause of the error much better than a segmentation violation caused by accessing a non-list as if it were a list... Finally note that at least it's reasonably consistent: newlistobject() returns an "object*", and getlistsize() takes one... > Can this be added to the "Clean Up List"??? Even if I did agree that it was a "good thing", cleaning this up would be a major, boring coding effort, because (unlike identifier changes) it can't be automated (or the automation would be as least as much work). --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Fri, 18 Jun 1993 17:11:02 +0200 Replied: "Lance Ellinghouse <lance@markv.com> " Replied: Fri, 18 Jun 1993 16:58:14 +0200 Replied: "Lance Ellinghouse <lance@markv.com> python-list" Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA10360 (5.65b/3.8/CWI-Amsterdam); Wed, 16 Jun 1993 18:29:01 +0200 From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: Guido.van.Rossum@cwi.nl Subject: Re: incorrect prototypes?? Date: Wed, 16 Jun 93 9:28:07 PDT Message-Id: <9306160928.aa18599@hermix.markv.com> >> Is there a reason that things like getlistsize() take >> a 'object *' instead of a 'listobject *' ???? >> >> This does not make much sense... > >This was done on purpose, because in many cases one has received an >"object*" (e.g. as an argument), detects that it is a list by using >"is_listobject()", and then wants to access it as a list. If all the >list-specific functions took a "listobject*" as argument, one would >either have to copy the object into a local variable of that type, or >use a cast on each call. I am not very fond of casts (since the >compiler will happily cast e.g. a "char*" to "listobject*") so I >prefer to minimize their number. I do not use 'object *' at all in my code. If I did, all would work fine, but then the compiler would not warn me that I am passing things where they should not be. Currently I am having to cast everything because they are NOT prototyped using 'listobject *'. :( Looks like different programmig styles have clashed. Oh well.. >It's true that now there's a cast inside listgetsize(), but that's one >cast per function definition instead of one cast per function call. >Also note that getlistsize() tests its argument for list-ness. >Strictly spoken this should be redundant, but many people (including >me!) sometimes write sloppy code that doesn't always check the types >of objects passing through a function. The function err_badcall() >(used in such occasions) currently raises an exception, but can easily >be changed to call abort(), which pin-points the cause of the error >much better than a segmentation violation caused by accessing a >non-list as if it were a list... All functions should test for the correct type being passed in. This is a given. I would feel the code was VERY broken if it did NOT check for this. By always using the correct type, 'listobject *' or 'tupleobject *', instead of the generic 'object *', it also makes programs easier to tell what is going on (at least I think so..), but then I have to deal with ANSI compilers that complain on every function call that I am passing the wrong type. So I either cast EVERYTHING (what a waste!) or I change the xxobject.h files (as I have done) to accept the correct type. This will also force the compiler to give a warning/error if I am passing in a non-typed object, i.e. 'object *', instead of the correct one. Makes you look over your code a little more. >Finally note that at least it's reasonably consistent: newlistobject() >returns an "object*", and getlistsize() takes one... I think this is wrong. newlistobject() should return a 'listobject *' instead of a 'object *'. It may be consistent, but I think it is wrong. If I am the only one in the world that does feel this way, I will shut my mouth and keep quiet. Lance Ellinghouse lance@markv.com Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA22543 (5.65b/3.8/CWI-Amsterdam); Fri, 18 Jun 1993 16:58:14 +0200 Received: by voorn.cwi.nl with SMTP id AA24762 (5.65b/3.8/CWI-Amsterdam); Fri, 18 Jun 1993 16:58:14 +0200 Message-Id: <9306181458.AA24762=guido@voorn.cwi.nl> To: Lance Ellinghouse <lance@markv.com> Cc: python-list@cwi.nl Subject: Re: incorrect prototypes?? In-Reply-To: Your message of "Wed, 16 Jun 1993 09:28:07 MDT." <9306160928.aa18599@hermix.markv.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Fri, 18 Jun 1993 16:58:14 +0200 Sender: Guido.van.Rossum@cwi.nl [Lance sent me a private reply, probably by mistake (since I first sent him a private reply by mistake). I quote liberally from his reply.] > I do not use 'object *' at all in my code. If I did, all would > work fine, but then the compiler would not warn me that I am > passing things where they should not be. Currently I am > having to cast everything because they are NOT prototyped using > 'listobject *'. :( Looks like different programmig styles have > clashed. Oh well.. I don't see how you can live without "object*" in general. (Of course I don't know how much code you have and how general it is.) Take for instance a C function called from Python that takes a list of integers as argument, and has to access the element. Python's type system makes it impossible to enforce that the list items are indeed integers, so the function has to check this. The code would look more or less like this: object * sum_list(dummy, arg) object *dummy, *arg; { int i, n; long sum; if (arg == NULL || !is_listobject(args)) { err_set(TypeError); return NULL; } n = getlistsize(arg); sum = 0; for (i = 0; i < n; i++) { object *item = getlistitem(arg, i); if (!is_intobject(item)) { err_set(TypeError); return NULL; } sum = sum + getintitem(item); } return newintobject(sum); } (Suppose this can be called directly as a function in a built-in module.) Now we don't *know* that arg is a list object until we've tested it, so it would be lying to declare it as such. The same holds for item. Also, note that the function has to be declared object* even though we know it will always return an intobject* (or NULL), since it has to conform to the general prototype for built-in functions. This means that if newintobject() were declared to return intobject* instead of object*, we would need another cast for the return value. If Python were implemented in C++, things would be different: explicit casts from specialized object types to generic object* would be unnecessary, and casts from object* to any particular object type could be handled differently (there's quite a nice C++ idiom for this that combines the cast and the check for object type). But we're using plain C, and I maintain that having most functions take and return object* and do some checking is the best compromise. (It's different in parts of the interpreter where objects' members are accessed frequently; there the correct type must be used; but this is not for general consumption...) > All functions should test for the correct type being passed in. > This is a given. I would feel the code was VERY broken if it did NOT > check for this. No. Functions shouldn't have to check when the type has already been checked by the compiler. The point is if every routine checked its arguments, there would be a lot of redundant checking going on (since often there are several levels of function calls passing each other objects that have already been verified). The function that casts an object* to listobject* is responsible for only applying the cast if it is valid. > I think this is wrong. newlistobject() should return a 'listobject *' > instead of a 'object *'. It may be consistent, but I think it is wrong. > If I am the only one in the world that does feel this way, I will > shut my mouth and keep quiet. Actually, I enjoy discussions like this, but so far few people have joined in, so I am here on my own defending some questional practice... (Maybe they are still waiting for my revised name changing proposal? Hold your breath, I'm working on it...) --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA26445 (5.65b/3.8/CWI-Amsterdam); Fri, 18 Jun 1993 18:57:04 +0200 Received: from eng2.sequent.com by gateway.sequent.com (5.61/1.34) id AA09335; Fri, 18 Jun 93 09:58:16 -0700 Received: by eng2.sequent.com (5.65/1.34) id AA16533; Fri, 18 Jun 93 09:56:50 -0700 Message-Id: <9306181656.AA16533@eng2.sequent.com> To: Guido.van.Rossum@cwi.nl Cc: lance@markv.com, python-list@cwi.nl Subject: Re: incorrect prototypes?? Priority: Normal Precedence: first-class Organization: Sequent Computer Systems, Inc. Service Technology - MailStop: WIL2-610 15450 S.W. Koll Parkway Beaverton, OR 97006-6063 X-Phone: (503) 578-4404 X-Fax: (503) 578-4540 X-Uucp: ...!uunet!sequent!jaap X-Internet: jaap@sequent.com X-Face: C4Cnai$>Eja5I6Vq?(gdN#SXX#`-XgAnmUn&e54sx7@1>q@vkrd_XnH![P>w.:7IJJ;{Bts WJd)u&G!V}0OR?2o5cUgIY}.T{g]PMC=*~]3n_t)S-ZkC(WG}3:#hcA6Oazx:}yc&k,hsF7D},7x>l nyfRjO7$@]fHBN>aC9-M3pKfbYHiy!PWD{_bx~fo})b4tU.;Ao%x[upCI, In-Reply-To: Guido.van.Rossum@cwi.nl's message of Fri, 18 Jun 1993 16:58:14 +0200. <9306181458.AA24762=guido@voorn.cwi.nl> Date: Fri, 18 Jun 1993 09:56:49 -0700 From: Jaap Vermeulen <jaap@sequent.com> | Actually, I enjoy discussions like this, but so far few people have | joined in, so I am here on my own defending some questional | practice... I think it's a matter of programming style for those routines that are not part of the interface to the python engine. Somewhere you have to cast, and it is a question of semantics whether you do the check in the caller or the callee. Here it looks like getlistsize() serves the dual role of checking its argument *and* returning the size. Of course most of the callers don't use this feature and you'll end up with a redundant check. Either way, I think I would gravitate towards Guido approach since I find it simpler and more elegant (casts are not my favorite either), even if it means some redundant checks. -Jaap- -- Jaap Vermeulen +--------------------------+ | Sequent Computer Systems | Internet : jaap@sequent.com | Beaverton, Oregon | Uucp : ...uunet!sequent!jaap +--------------------------+ Received: from relay1.UU.NET by charon.cwi.nl with SMTP id AA27633 (5.65b/3.8/CWI-Amsterdam); Fri, 18 Jun 1993 19:37:35 +0200 Received: from vicorp.com (via vicorp.vicorp.com) by relay1.UU.NET with SMTP (5.61/UUNET-internet-primary) id AA18731; Fri, 18 Jun 93 13:37:24 -0400 Received: from zippy.vicorp.com by vicorp.com (4.1/SMI-4.1) id AA01391; Fri, 18 Jun 93 13:36:49 EDT Date: Fri, 18 Jun 93 13:36:49 EDT From: Donald Beaudry <don@vicorp.com> Message-Id: <9306181736.AA01391@vicorp.com> To: python-list@cwi.nl In-Reply-To: Guido.van.Rossum@cwi.nl's message of Fri, 18 Jun 1993 16:58:14 +0200 <9306181458.AA24762=guido@voorn.cwi.nl> Subject: incorrect prototypes?? >> I think this is wrong. newlistobject() should return a 'listobject *' >> instead of a 'object *'. It may be consistent, but I think it is wrong. >> If I am the only one in the world that does feel this way, I will >> shut my mouth and keep quiet. > Actually, I enjoy discussions like this, but so far few people have > joined in, so I am here on my own defending some questional > practice... Well, I guess I should toss my opinion in so that Guido does not have to feel alone. I don't think that the practice of using object* for everything is questionable at all. I even think that it is necessary. Python is a dynamically typed language. Since C does not support dynamic type checking it is up to the programmer to do it. Specifically, it is up to the implementor of the object. All objects should have a public interface and that interface must check that object passed is really of the same type as expected. In fact, the static type of the object (the C structure) should be hidden from the users of the object. It is up to the implementor of the object to decide what attributes are visible and to provide an interface to those attributes. --Don ______ ______ \_\_\_\ /#/#/#/ \_\_\_\ ______ \_\_\_V#/#/#/ Donald Beaudry don@vicorp.com \_\_/#/#/#/ V. I. Corporation uunet!vicorp!don \_/#/#/#/ 47 Pleasant Street PHONE: (413) 586-4144 V#/#/#/ Northampton, MA 01060 FAX: (413) 586-3805 Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA29055 (5.65b/3.8/CWI-Amsterdam); Fri, 18 Jun 1993 20:11:55 +0200 To: python-list@cwi.nl Subject: Prototypes.. Date: Fri, 18 Jun 93 11:10:41 PDT From: lance@markv.com Sender: lance@markv.com Message-Id: <9306181110.aa05123@hermix.markv.com> Source-Info: From (or Sender) name not authenticated. Well since everyone seems to agree with the current style of prototypes, I will just have to get used to it and use it. Not a major problem.. Sorry for wasting soo much bandwidth on this topic. Lance Ellinghouse lance@markv.com Replied: Sat, 19 Jun 1993 10:55:03 +0200 Replied: "Doug Moen <dmoen@utcc.utoronto.ca> " Received: from gpu.utcc.utoronto.ca by charon.cwi.nl with SMTP id AA27899 (5.65b/3.8/CWI-Amsterdam); Sat, 19 Jun 1993 06:09:02 +0200 Received: by gpu.utcc.utoronto.ca id <18552>; Sat, 19 Jun 1993 00:08:48 -0400 From: Doug Moen <dmoen@utcc.utoronto.ca> To: python-list@cwi.nl Subject: type casting and c++ Message-Id: <93Jun19.000848edt.18552@gpu.utcc.utoronto.ca> Date: Sat, 19 Jun 1993 00:08:37 -0400 > If Python were implemented in C++, things would be different: explicit > casts from specialized object types to generic object* would be > unnecessary, and casts from object* to any particular object type > could be handled differently (there's quite a nice C++ idiom for this > that combines the cast and the check for object type). This sounds like a good argument for translating Python into C++. Here's another: that business of explicitly managing reference counts could be greatly simplified using C++ constructors and destructors. This would make the job of writing extension modules less error prone. Ignore for a moment the fact that it would be a lot of work, and consider this: Python is written in C because C is ubiquitous. Since Python began, C++ has become much more widely available. There are now multiple PC and Mac compilers, and GNU seems to cover the Unix platforms. Is C++ now sufficiently widely available that converting Python to C++ makes sense? To: Doug Moen <dmoen@utcc.utoronto.ca> Subject: Re: type casting and c++ In-reply-to: Your message of "Sat, 19 Jun 1993 00:08:37 MDT." <93Jun19.000848edt.18552@gpu.utcc.utoronto.ca> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Sat, 19 Jun 1993 10:55:03 +0200 Sender: guido > This sounds like a good argument for translating Python into C++. > Here's another: that business of explicitly managing reference counts > could be greatly simplified using C++ constructors and destructors. > This would make the job of writing extension modules less error prone. I tried setting up a scheme for automatic reference counting C++ once and soon found out that it incurs a lot more overhead than the way it's done manually in C now. The problem is that in many situations you don't need to change a reference count because you don't permanently store a copy of a pointer, you only "peek" at it. A simple-minded reference-counting pointer type in C++ won't know this and will add referece count adjustments in many more places than necessary. When this happens at the lower levels it will really slow things down. > Ignore for a moment the fact that it would be a lot of work, > and consider this: Python is written in C because C is ubiquitous. > Since Python began, C++ has become much more widely available. > There are now multiple PC and Mac compilers, and GNU seems to cover the > Unix platforms. Is C++ now sufficiently widely available that converting > Python to C++ makes sense? I have my doubts. C++ is more widely available, but it is not by any measure "ubiquitous". It is also not yet stable (templates? exceptions? multiple inheritance?) It is also bigger, slower, and harder to learn. Some people even consider it as a failure because it leaves most of C's unsafe features intact. I like to see Python as a "democratic" language, available for all. (That's why I distribute Mac and PC binaries -- most owners of those machines don't have *any* compiler.) Requiring people to acquire C++ before building Python is one more burden and will surely slow down Python's acceptance. But, feel free to prove me wrong... --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA06500 (5.65b/3.8/CWI-Amsterdam); Sat, 19 Jun 1993 10:55:40 +0200 Received: by voorn.cwi.nl with SMTP id AA26409 (5.65b/3.8/CWI-Amsterdam); Sat, 19 Jun 1993 10:55:39 +0200 Message-Id: <9306190855.AA26409=guido@voorn.cwi.nl> To: python-list@cwi.nl Subject: Re: type casting and c++ In-Reply-To: Your message of "Sat, 19 Jun 1993 00:08:37 MDT." <93Jun19.000848edt.18552@gpu.utcc.utoronto.ca> X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Sat, 19 Jun 1993 10:55:39 +0200 From: Guido van Rossum <Guido.van.Rossum@cwi.nl> > This sounds like a good argument for translating Python into C++. > Here's another: that business of explicitly managing reference counts > could be greatly simplified using C++ constructors and destructors. > This would make the job of writing extension modules less error prone. I tried setting up a scheme for automatic reference counting C++ once and soon found out that it incurs a lot more overhead than the way it's done manually in C now. The problem is that in many situations you don't need to change a reference count because you don't permanently store a copy of a pointer, you only "peek" at it. A simple-minded reference-counting pointer type in C++ won't know this and will add referece count adjustments in many more places than necessary. When this happens at the lower levels it will really slow things down. > Ignore for a moment the fact that it would be a lot of work, > and consider this: Python is written in C because C is ubiquitous. > Since Python began, C++ has become much more widely available. > There are now multiple PC and Mac compilers, and GNU seems to cover the > Unix platforms. Is C++ now sufficiently widely available that converting > Python to C++ makes sense? I have my doubts. C++ is more widely available, but it is not by any measure "ubiquitous". It is also not yet stable (templates? exceptions? multiple inheritance?) It is also bigger, slower, and harder to learn. Some people even consider it as a failure because it leaves most of C's unsafe features intact. I like to see Python as a "democratic" language, available for all. (That's why I distribute Mac and PC binaries -- most owners of those machines don't have *any* compiler.) Requiring people to acquire C++ before building Python is one more burden and will surely slow down Python's acceptance. But, feel free to prove me wrong... --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Fri, 02 Jul 1993 12:43:15 +0200 Replied: "Jaap Vermeulen <jaap@sequent.com> python-list" Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA17074 (5.65b/3.8/CWI-Amsterdam); Fri, 2 Jul 1993 02:30:02 +0200 Received: from eng2.sequent.com by gateway.sequent.com (5.61/1.34) id AA18751; Thu, 1 Jul 93 17:31:04 -0700 Received: by eng2.sequent.com (5.65/1.34) id AA05618; Thu, 1 Jul 93 17:29:55 -0700 Message-Id: <9307020029.AA05618@eng2.sequent.com> To: Python Mailing List <python-list@cwi.nl> Subject: Did somebody implement a curses interface? Priority: Normal Precedence: first-class Organization: Sequent Computer Systems, Inc. Service Technology - MailStop: WIL2-610 15450 S.W. Koll Parkway Beaverton, OR 97006-6063 X-Phone: (503) 578-4404 X-Fax: (503) 578-4540 X-Uucp: ...!uunet!sequent!jaap X-Internet: jaap@sequent.com X-Face: C4Cnai$>Eja5I6Vq?(gdN#SXX#`-XgAnmUn&e54sx7@1>q@vkrd_XnH![P>w.:7IJJ;{Bts WJd)u&G!V}0OR?2o5cUgIY}.T{g]PMC=*~]3n_t)S-ZkC(WG}3:#hcA6Oazx:}yc&k,hsF7D},7x>l nyfRjO7$@]fHBN>aC9-M3pKfbYHiy!PWD{_bx~fo})b4tU.;Ao%x[upCI, Date: Thu, 01 Jul 93 17:29:54 PDT From: Jaap Vermeulen <jaap@sequent.com> Guess what, I could use a curses interface in Python. There was some traffic about a curses interface some time ago, but no definite answer. It looked like people were porting a curses interface or a subset of it. Is there a curses or curses-like module out there that I could use? Thanks, -Jaap- -- Jaap Vermeulen +--------------------------+ | Sequent Computer Systems | Internet : jaap@sequent.com | Beaverton, Oregon | Uucp : ...uunet!sequent!jaap +--------------------------+ Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA17525 (5.65b/3.8/CWI-Amsterdam); Fri, 2 Jul 1993 02:54:00 +0200 From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: jaap@sequent.com Subject: Re: Did somebody implement a curses interface? Cc: python-list@cwi.nl Date: Thu, 1 Jul 93 17:53:00 PDT Message-Id: <9307011753.aa26428@hermix.markv.com> I am looking for a curses package also... but noone has come up with one yet.. Maybe we can make it together?? Lance lance@markv.com Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA05870 (5.65b/3.8/CWI-Amsterdam); Fri, 2 Jul 1993 12:43:16 +0200 Received: by voorn.cwi.nl with SMTP id AA04061 (5.65b/3.8/CWI-Amsterdam); Fri, 2 Jul 1993 12:43:15 +0200 Message-Id: <9307021043.AA04061=guido@voorn.cwi.nl> To: Jaap Vermeulen <jaap@sequent.com> Cc: python-list@cwi.nl Subject: Re: Did somebody implement a curses interface? In-Reply-To: Your message of "Thu, 01 Jul 1993 17:29:54 MDT." <9307020029.AA05618@eng2.sequent.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Fri, 02 Jul 1993 12:43:15 +0200 Sender: Guido.van.Rossum@cwi.nl > Guess what, I could use a curses interface in Python. There was some > traffic about a curses interface some time ago, but no definite > answer. It looked like people were porting a curses interface or a > subset of it. Is there a curses or curses-like module out there that I > could use? I haven't heard of curses interfaces for Python -- I'm afraid most of its users have bitmapped or or color graphics displays... I suppose you could use the alfa version of STDWIN -- it's not exactly curses but has similar functionality. And guess what, your programs will be portable to X11 as well! --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA23720 (5.65b/3.8/CWI-Amsterdam); Sun, 4 Jul 1993 01:51:31 +0200 Received: by hermix.markv.com id ab28473; 3 Jul 93 16:51 PDT From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: python-list@cwi.nl Subject: setmember() Date: Sat, 3 Jul 93 16:39:25 PDT Message-Id: <9307031639.aa27852@hermix.markv.com> Is there a reason that T_STRING types of memberlist elements cause a "TypeError" to be raised? I have an element that I NEED to be as T_STRING type, but setmember() will not allow that. You can READ T_STRING types, but now WRITE to it.. I know there is a problem with the possibility of overwriting the end of the buffer passed in, but this can be tested for.. Since there will ALWAYS going to be an element AFTER a T_STRING element, we could have it look at the offset on the element AFTER the T_STRING element and the subtract 1 and then that will give the length allowed. If the string is longer than that length, then an exception could be raised OR just truncate.. Comments?? Lance Ellinghouse lance@markv.com Replied: Sun, 04 Jul 1993 22:22:38 +0200 Replied: "Lance Ellinghouse <lance@markv.com> python-list" Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA28005 (5.65b/3.8/CWI-Amsterdam); Sun, 4 Jul 1993 06:43:58 +0200 From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: Guido.van.Rossum@cwi.nl Subject: fixes to structmember.c Date: Sat, 3 Jul 93 21:43:23 PDT Message-Id: <9307032143.aa20925@hermix.markv.com> Here are CVS diffs for a corrected version of structmember.c. This fixes a couple bugs in the parsing routines for T_CHAR and puts the fix I sugested for T_STRING... Lance Ellinghouse lance@markv.com ====== =================================================================== RCS file: /u/lance/CVS/python/src/structmember.c,v retrieving revision 1.1.1.1 diff -r1.1.1.1 structmember.c 104c104 < if (*(char**)addr == NULL) { --- > if ((char*)addr == NULL) { 109c109 < v = newstringobject(*(char**)addr); --- > v = newstringobject((char*)addr); 143c143 < if (l->readonly || l->type == T_STRING) { --- > if (l->readonly) { 148a149,163 > case T_STRING: > { > int i, j; > struct memberlist *g = l; > if (!is_stringobject(v)) { > err_badarg(); > return -1; > } > g++; > i = g->offset; > j = i - l->offset - 1; > strncpy((char *)addr,getstringvalue(v),j); > *(char *)(addr+j) = '\0'; > break; > } 224a240 > break; To: Lance Ellinghouse <lance@markv.com> cc: python-list Subject: Re: fixes to structmember.c In-reply-to: Your message of "Sat, 03 Jul 1993 21:43:23 MDT." <9307032143.aa20925@hermix.markv.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Sun, 04 Jul 1993 22:22:39 +0200 Sender: guido Lance writes: > Is there a reason that T_STRING types of memberlist elements > cause a "TypeError" to be raised? > > I have an element that I NEED to be as T_STRING type, but setmember() > will not allow that. You can READ T_STRING types, but now WRITE to it.. > I know there is a problem with the possibility of overwriting the end > of the buffer passed in, but this can be tested for.. > > Since there will ALWAYS going to be an element AFTER a T_STRING element, > we could have it look at the offset on the element AFTER the T_STRING > element and the subtract 1 and then that will give the length allowed. > If the string is longer than that length, then an exception could be > raised OR just truncate.. The T_STRING member type is intended for struct members of type "char *", not for struct members of type "char[]" as you seem to be implying (the patch you sent me privately changes the meaning to "char[]"!) My preferred solution would be to add a new type T_BUFFER which means a member of type char[], with a way to specify the length explicitly. (I don't like the idea of looking at the next element because theg elements may not be listed in ascending order, and sometimes some elements are not listed at all, e.g. when their type in inexpressible.) For binary compatibility (important in the light of dynamically loaded modules!), I would propose the following hack to store the length: the type proper is only the lower 4 bits (this is just sufficient for the current set of types), the length is in the upper 12 or 28 bits (12 bits on machines where ints are 2 bytes, like some Mac or PC compilers). This lets you specify buffers of up to 4095 bytes if you are careful. (Alternatively, you could overload the readonly field -- if it is <= 0, the value is writable, if it is > 0, it is readonly. This gives you 15 bits for the size.) Note that Donald Beaudry has proposed (in private email) a much more general mechanism which should take care of this and other restrictions of the structmember.[ch] files. However this would require rewriting all code that currently uses structmember, and also I believe Donald was still pondering ways to make his solution even more general, so I'm not sure whether it will appear in the next release... --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA06129 (5.65b/3.8/CWI-Amsterdam); Sun, 4 Jul 1993 22:22:39 +0200 Received: by voorn.cwi.nl with SMTP id AA09075 (5.65b/3.8/CWI-Amsterdam); Sun, 4 Jul 1993 22:22:39 +0200 Message-Id: <9307042022.AA09075=guido@voorn.cwi.nl> To: Lance Ellinghouse <lance@markv.com> Cc: python-list@cwi.nl Subject: Re: fixes to structmember.c In-Reply-To: Your message of "Sat, 03 Jul 1993 21:43:23 MDT." <9307032143.aa20925@hermix.markv.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Sun, 04 Jul 1993 22:22:39 +0200 Sender: Guido.van.Rossum@cwi.nl Lance writes: > Is there a reason that T_STRING types of memberlist elements > cause a "TypeError" to be raised? > > I have an element that I NEED to be as T_STRING type, but setmember() > will not allow that. You can READ T_STRING types, but now WRITE to it.. > I know there is a problem with the possibility of overwriting the end > of the buffer passed in, but this can be tested for.. > > Since there will ALWAYS going to be an element AFTER a T_STRING element, > we could have it look at the offset on the element AFTER the T_STRING > element and the subtract 1 and then that will give the length allowed. > If the string is longer than that length, then an exception could be > raised OR just truncate.. The T_STRING member type is intended for struct members of type "char *", not for struct members of type "char[]" as you seem to be implying (the patch you sent me privately changes the meaning to "char[]"!) My preferred solution would be to add a new type T_BUFFER which means a member of type char[], with a way to specify the length explicitly. (I don't like the idea of looking at the next element because theg elements may not be listed in ascending order, and sometimes some elements are not listed at all, e.g. when their type in inexpressible.) For binary compatibility (important in the light of dynamically loaded modules!), I would propose the following hack to store the length: the type proper is only the lower 4 bits (this is just sufficient for the current set of types), the length is in the upper 12 or 28 bits (12 bits on machines where ints are 2 bytes, like some Mac or PC compilers). This lets you specify buffers of up to 4095 bytes if you are careful. (Alternatively, you could overload the readonly field -- if it is <= 0, the value is writable, if it is > 0, it is readonly. This gives you 15 bits for the size.) Note that Donald Beaudry has proposed (in private email) a much more general mechanism which should take care of this and other restrictions of the structmember.[ch] files. However this would require rewriting all code that currently uses structmember, and also I believe Donald was still pondering ways to make his solution even more general, so I'm not sure whether it will appear in the next release... --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA10873 (5.65b/3.8/CWI-Amsterdam); Mon, 5 Jul 1993 00:20:59 +0200 Received: by voorn.cwi.nl with SMTP id AA09207 (5.65b/3.8/CWI-Amsterdam); Mon, 5 Jul 1993 00:20:58 +0200 Message-Id: <9307042220.AA09207=guido@voorn.cwi.nl> To: python-list@cwi.nl Subject: THE GREAT RENAMING -- SECOND DRAFT From: Guido.van.Rossum@cwi.nl X-Organization: CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Mon, 05 Jul 1993 00:20:57 +0200 Sender: Guido.van.Rossum@cwi.nl I know you thought I'd forgotten about it, but no, I was just busy with other things (as well as a little bored with the long list of new names to invent...). Here's the result of my workon the matter, in two parts: (1) a modified version of the naming conventions proposal; (2) a list giving new names for almost all "global" (in some sense) names in the current interpreter. This is not cast in concrete, so don't use this yet, but read it through if you have time, and let me know where the weak spots are. --Guido ======================================================================== [Change bars indicate changes with respect to the first draft.] | Naming Conventions -- Second Draft Proposal | ******************************************* It is quite easy to extend Python with a new module written in C. It should be equally easy to embed the Python interpreter as a library in an existing (or new) application. This is indeed possible, but there is a potential problem when the application is large: the Python interpreter library defines many external names that may clash with names defined by the application. To a lesser extend the macros, | structures and typedefs defined in Python's public header files may also clash with application-defined names (or with names defined by other libraries, when the application needs to use several libraries in one file). This article proposes a change to the naming of all external functions, macros, structures, typedefs etc. that are in any way visible to the application with the intent to make clashes avoidable. (This excludes the names of static functions and variables, local variables, structure members, and macros, structures and typedefs | defined in .c files or .h files for internal use only.) At the same time the set of names is somewhat rationalized to make it easier to guess where a name is defined. The purpose of this proposal is to get feedback. This is your chance to make your voice heard! Please evaluate every aspect of the proposal and let me know whether you like it or not. No effort has yet begun to implement the proposal, so there are no big costs involved in changes to the proposal. Your opinion is especially important if you have written (or are maintaining) code that extends the Python interpreter, since you will have to change your code and learn to use the new conventions. | This is the second draft; the next version will be implemented, | so this is your last chance to make your voice heard. Note that these changes affect the C code that implements the Python interpreter (and its extensions) only; the Python language as seen by Python programmers will remain unchanged! Basic Conventions ================= The mechanism to avoid clashes is to prefix all relevant names with the string Py. This gives an application a very simple way to avoid clashes: simply don't define names starting with Py in the application. A similar mechanism is successfully used by most widespread libraries, e.g. X. The full naming scheme gives functions a name as follows: | [_]Py<Module>_<Function>, where <Module> is the (sometimes abbreviated) name of the module to which the function belongs (this may also be a basic type), and <Function> is a descriptive name for the function. | [_] stands for an optional underscore (for internal functions). The <Module> and <Function> parts use a mixed-case convention: each is spelled with an initial capital letter, and if they consist of multiple words each word has an initial capital. Embedded underscores are not used except between <Module> and <Function>. Some examples: | PyObject_Print PyList_Append PyList_GetItem | PyList_Alloc | PyString_AsString PyErr_SetString | Some utility functions have a prefix of just Py_, e.g. | | Py_FatalError Py_MakeValue Global variables are named using similar conventions, e.g. PyList_Type PyExc_ZeroDivisionError | Names that have to be global for some reason but are not part of the official interface have an initial underscore, e.g. _Py_RefTotal | _PyObject_New | Macros that behave like functions are named like functions, e.g.: | PyList_Valid | _Py_NewReference | Macros used as symbolic constants and enum values have a second part that is entirely in capitals and uses underscores to separate words. So do enums. E.g.: Py_PRINT_RAW | Macros that are not completely like functions (e.g. have a | typedef as argument or may evaluate one or more arguments several | times, or unsafe inline versions) also follow this convention, e.g.: | | Py_INCREF | PyFloat_AS_DOUBLE Typedefs contain no underscore; they consist of Py followed by one or more words with initial capitals, e.g.: PyObject PyListObject | PyNumberMethods Most of these typedef names correspond to structures; the structure tag will be the typedef name prefixed with an underdscore. Note that the current system has a number of structures that are not covered by typedefs. These will be given typedef names. | For example: | | PyMemberDef | PyMethodDef Also note that pointer types will continue to be written with the "*" notation, e.g. "PyObject *". Pointers in C have sufficiently special semantics to make it important in practice to know whether a particular variable is a pointer; e.g. Python frequently uses casts between various object pointers. | Typedefs do not end in "_t". I find this ugly and unnecessary. | For now, header file names will remain unchanged. In the future, | header files may be renamed to <Py/List.h> etc., with <Py/Python.h> | a convenience header like the current "allobjects.h". (There was | considerable diversity in the suggestions for a new directory | structure, so for now I'll leave it unchanged until I have thought | about it more.) | Header files will be protected against multiple inclusion with a | macro and an #ifdef, as follows: | | #ifndef PyFOO_H | #define PyFOO_H | . | . (entire contents of file goes here) | . | #endif /* PyFOO_H */ Transition Period ================= During a transition period, which will last at least two releases that each live at least 3 months (giving a total of at least 6 months), it will be possible to use the old names and the new names together. The transition mechanism uses #define to identify the new and old names. In the first transition release, the (majority of) source code will still use the old names, including the old header file names, but macros will be defined to support the use of the new names, e.g.: #define PyObject object In the second transition release, the source code will use the new names, also for header file names, and macros will be defined to support code that still uses the old names, e.g.: #define object PyObject | Header file names may be changed in the second transition release | (if I can agree with myself on a good naming scheme). In both transition releases, the compatibility macros will be gathered in a single header file (a different one each time!). A Python script will be provided which translates C code from the old to the new naming conventions with 99% accuracy. It remains to be seen whether occurrences in comments should be replaced; when comments refer to functions and typedefs etc., they should, but some names (e.g. object!) can also be used as a noun, so global substitutions may cause undesired effects. Also, there are some situations where names occurring in strings must be substituted! | (the sections on other changes and an alternate proposal have been | deleted) ======================================================================== # This file contains an almost complete list of identifiers that will # change at the Great Renaming. The rules are explained in the file # NAMING; this file just contains a list of mappings. With few # exceptions, this file can be used as input for a renaming script that # I have devised (which assumes its input lines contain pairs of old # name and new name after comment stripping). Note that names which # are global by mistake in the current are not listed here; they will # be made static (manually). There may also be some names here that # are not defined in the 0.9.8 release; these have been introduced in # the code after that release. I've attempted to remove most of these # but sometimes I may not have remembered their status correctly... # ====== CPP symbols used to switch on ====== NDEBUG Py_NO_DEBUG TRACE_REFS Py_TRACE_REFS REF_DEBUG Py_REF_DEBUG USE_... Py_USE_... HAVE_PROTOTYPES Py_HAVE_PROTOTYPES HAVE_STDLIB Py_HAVE_STDLIB # Each .h file "foo.h" will be protected by a macro and ifdef as follows: # #ifndef PyFOO_H # #define PyFOO_H # . # . (entire contents of file goes here) # . # #endif /* PyFOO_H */ # ====== Data ====== # --- Misc global data --- FalseObject _Py_ZeroStruct NoObject _Py_NoneStruct TrueObject _Py_TrueStruct debugging Py_DebugFlag gram _PyParser_Grammar sys_profile _PySys_ProfileFunc sys_trace _PySys_TraceFunc threads_started _PyThread_Started tok_name _PyParser_TokenNames verbose Py_VerboseFlag # --- Built-in exceptions --- AttributeError PyExc_AttributeError EOFError PyExc_EOFError IOError PyExc_IOError ImportError PyExc_ImportError IndexError PyExc_IndexError KeyError PyExc_KeyError MemoryError PyExc_MemoryError NameError PyExc_NameError OverflowError PyExc_OverflowError RuntimeError PyExc_RuntimeError SyntaxError PyExc_SyntaxError SystemError PyExc_SystemError TypeError PyExc_TypeError ValueError PyExc_ValueError ZeroDivisionError PyExc_ZeroDivisionError KeyboardInterrupt PyExc_KeyboardInterrupt SystemExit PyExc_SystemExit # --- Built-in type objects --- (only used through is_<type>object() macros) # Atomic basic types Floattype PyFloat_Type Inttype PyInt_Type Longtype PyLong_Type Notype PyNothing_Type Stringtype PyString_Type # Also composite (sequence) Typetype PyType_Type # Composite basic types Listtype PyList_Type Dicttype PyDict_Type Tupletype PyTuple_Type # I/O types Filetype PyFile_Type # Interpreter related types Classtype PyClass_Type Functype PyFunction_Type Instancemethodtype PyMethod_Type Instancetype PyInstance_Type Methodtype PyCFunction_Type # Split in CMethod, CFunction? Moduletype PyModule_Type # Interpreter internal types Codetype PyCode_Type Frametype PyFrame_Type # ====== Typedefs ====== *object PyObject #varobject no longer visible for users floatobject PyFloatObject intobject PyIntObject longobject PyLongObject noobject PyNothingObject stringobject PyStringObject typeobject PyTypeObject listobject PyListObject dictobject PyDictObject tupleobject PyTupleObject fileobject PyFileObject classobject PyClassObject codeobject PyCodeObject frameobject PyFrameObject funcobject PyFunctionObject instancemethodobject PyMethodObject instanceobject PyInstanceObject methodobject PyCFunctionObject # Split in CMethod, CFunction? moduleobject PyModuleObject number_methods PyNumberMethods sequence_methods PySequenceMethods mapping_methods PyMappingMethods # ====== Funny CPP macros ====== OB_HEAD PyObject_HEAD OB_VARHEAD PyObject_VAR_HEAD OB_HEAD_INIT PyObject_HEAD_INIT NEWOBJ PyObject_NEW NEWVAROBJ PyObject_NEW_VAR PROTO Py_PROTO PROTO Py_FPROTO # For ANY* I break my own rule of not defining names for pointer # types, since here it is essential that the pointer not be # dereferenced! # (My script doesn't understand this, I'll fix it manually) ANY* PyUnivPtr # either char* or void* NEW PyMem_NEW RESIZE PyMem_RESIZE DEL PyMem_DEL XDEL PyMem_XDEL MALLARG size_t # this macro is no longer needed BGN_SAVE Py_BEGIN_ALLOW_THREADS RET_SAVE Py_BLOCK_THREADS RES_SAVE Py_UNBLOCK_THREADS END_SAVE Py_END_ALLOW_THREADS # ====== Enumerated Values ====== # E_OK, etc.: unchanged (used internally only) # T_INT, etc.: for now, these remain the same; in the future # structmember.h will be replaced by a more powerful (extensible) # module where types are expressed by strings. # ====== Structure tags ====== # Avoid completely (use forward typedefs instead) # (My script can't handle those, wil lfix manually) #struct memberlist PyMemberDef #struct methodlist PyMethodDef #(etc.) # ====== Type tests ====== is_floatobject PyFloat_Check is_intobject PyInt_Check is_longobject PyLong_Check is_noobject PyNothing_Check is_stringobject PyString_Check is_typeobject PyType_Check is_listobject PyList_Check is_dictobject PyDict_Check is_tupleobject PyTuple_Check is_fileobject PyFile_Check is_classobject PyClass_Check is_codeobject PyCode_Check is_frameobject PyFrame_Check is_funcobject PyFunction_Check is_instancemethodobject PyMethod_Check is_instanceobject PyInstance_Check is_methodobject PyCFunction_Check # Split in CMethod, CFunction? is_moduleobject PyModule_Check # Operations on built-in types # --- Generic Object Operations --- INCREF Py_INCREF # uses arg multiple times DECREF Py_DECREF # " " " " XINCREF Py_XINCREF XDECREF Py_XDECREF NEWREF _Py_NewReference DELREF _Py_Dealloc UNREF _Py_ForgetReference None Py_None False Py_False True Py_True cmpobject PyObject_Compare getattr PyObject_GetAttrString getattro PyObject_GetAttr hashobject PyObject_Hash newobject _PyObject_New newvarobject _PyObject_NewVar printobject PyObject_Print reprobject PyObject_Repr setattr PyObject_SetAttrString setattro PyObject_SetAttr testbool PyObject_IsTrue # --- flags for PyObject_Print --- PRINT_RAW Py_PRINT_RAW # --- Atomic basic objects --- float_buf_repr PyFloat_AsString # need to reverse arguments getfloatvalue PyFloat_AsDouble GETFLOATVALUE PyFloat_AS_DOUBLE newfloatobject PyFloat_FromDouble getintvalue PyInt_AsLong GETINTVALUE PyInt_AS_LONG newintobject PyInt_FromLong alloclongobject _PyLong_New # used by marshal, mpz dgetlongvalue PyLong_AsDouble dnewlongobject PyLong_FromDouble getlongvalue PyLong_AsLong long_scan PyLong_FromString newlongobject PyLong_FromLong formatstring PyString_Format getstringsize PyString_Size getstringvalue PyString_AsString GETSTRINGVALUE PyString_AS_STRING joinstring PyString_Concat newsizedstringobject PyString_FromStringAndSize newstringobject PyString_FromString resizestring _PyString_Resize # --- Composite basic objects --- addlistitem PyList_Append getlistitem PyList_GetItem GETLISTITEM PyList_GET_ITEM getlistsize PyList_Size getlistslice PyList_GetSlice inslistitem PyList_Insert newlistobject PyList_New setlistitem PyList_SetItem setlistslice PyList_SetSlice sortlist PyList_Sort # These are different from the 0.9.8 distribution! Hope you get the gist. dictinsert PyDict_SetItemString dictlookup PyDict_GetItemString dictremove PyDict_DelItemString getmappingitems PyDict_Items getmappingkeys PyDict_Keys getmappingvalues PyDict_Values mappingclear PyDict_Clear mappinggetnext PyDict_Next mappinginsert PyDict_SetItem mappinglookup PyDict_GetItem mappingremove PyDict_DelItem newmappingobject PyDict_New gettupleitem PyTuple_GetItem GETTUPLEITEM PyTuple_GET_ITEM gettuplesize PyTuple_Size gettupleslice PyTuple_GetSlice newtupleobject PyTuple_New settupleitem PyTuple_SetItem # --- I/O Objects --- filegetline PyFile_GetLine getfilefile PyFile_AsFile newfileobject PyFile_FromString newopenfileobject PyFile_FromFile softspace PyFile_SoftSpace writeobject PyFile_WriteObject writestring PyFile_WriteString # --- Interpreter Related Objects --- # These are really all internal instancemethodgetclass PyMethod_Class instancemethodgetfunc PyMethod_Function instancemethodgetself PyMethod_Self issubclass PyClass_IsSubclass newclassobject PyClass_New newinstancemethodobject PyMethod_New newinstanceobject PyInstance_New block PyTryBlock extend_stack PyFrame_ExtendStack newframeobject PyFrame_New pop_block PyFrame_BlockPop setup_block PyFrame_BlockSetup getfunccode PyFunction_GetCode getfuncglobals PyFunction_GetGlobals newfuncobject PyFunction_New method PyCFunction findmethod Py_FindMethod # Will be replaced by another mechanism getmethod PyCFunction_GetFunction getself PyCFunction_GetSelf getvarargs PyCFunction_IsVarArgs newmethodobject PyCFunction_New getmoduledict PyModule_GetDict getmodulename PyModule_GetName newmoduleobject PyModule_New # ====== Text ====== # --- Parser and tokenizer --- (knows about tokens and grammar) addaccelerators PyGrammar_AddAccelerators finddfa PyGrammar_FindDFA labelrepr PyGrammar_LabelRepr listtree PyNode_ListTree addchild PyNode_AddChild freetree PyNode_Free newtree PyNode_New addtoken PyParser_AddToken delparser PyParser_Delete newparser PyParser_New parsefile PyParser_ParseFile parsestring PyParser_ParseString tok_1char PyToken_OneChar tok_2char PyToken_TwoChars tok_free PyTokenizer_Free tok_get PyTokenizer_Get tok_setupf PyTokenizer_FromFile tok_setups PyTokenizer_FromString # --- Compiler --- (knows about grammar and objects and opcodes) compile PyNode_Compile newcodeobject PyCode_New # --- Interpreter --- (knows about objects and opcodes) call_object PyEval_CallObject eval_code PyEval_EvalCode flushline Py_FlushLine getglobals PyEval_GetGlobals getlocals PyEval_GetLocals init_save_thread PyEval_InitThreads printtraceback PyErr_PrintTraceBack restore_thread PyEval_RestoreThread save_thread PyEval_SaveThread # --- Interpreter support --- tb_fetch PyTraceBack_Fetch tb_here PyTraceBack_Here tb_print PyTraceBack_Print tb_store PyTraceBack_Store add_module PyImport_AddModule doneimport PyImport_Cleanup get_modules PyImport_GetModuleDict import_module PyImport_ImportModule init_frozen PyImport_ImportFrozenModule initimport PyImport_Init reload_module PyImport_ReloadModule coerce PyNumber_Coerce getbuiltin PyBuiltin_GetObject initbuiltin PyBuiltin_Init initmarshal PyMarshal_Init rd_long PyMarshal_ReadLongFromFile rd_object PyMarshal_ReadObjectFromFile rds_object PyMarshal_ReadObjectFromString wr_long PyMarshal_WriteLongToFile wr_object PyMarshal_WriteObjectToFile initsys PySys_Init setpythonargv PySys_SetArgv setpythonpath PySys_SetPath sysget PySys_GetObject sysgetfile PySys_GetFile sysset PySys_SetObject # --- Embedding support --- compile_string Py_CompileString fatal Py_FatalError goaway Py_Exit initall Py_Initialize print_error PyErr_Print parse_file PyParser_SimpleParseFile parse_string PyParser_SimpleParseString run PyRun_AnyFile run_script PyRun_SimpleFile run_command PyRun_SimpleString run_file PyRun_File run_string PyRun_String run_tty_1 PyRun_InteractiveOne run_tty_loop PyRun_InteractiveLoop # --- Extension support --- getmember PyMember_Get setmember PyMember_Set initmodule Py_InitModule mkvalue Py_BuildValue vmkvalue Py_VaBuildValue # --- Get arguments --- getargs PyArg_Parse # getlonglistarg # unused -- will disappear # getlongtuplearg # unused -- will disappear # getshortlistarg # unused -- will disappear # getshorttuplearg # unused -- will disappear # --- Special set used by code generated by cgen.py (i.e. glmodule.c) --- getichararg PyArg_GetChar getidoublearray PyArg_GetDoubleArray getifloatarg PyArg_GetFloat getifloatarray PyArg_GetFloatArray getilongarg PyArg_GetLong getilongarray PyArg_GetLongArray getilongarraysize PyArg_GetLongArraySize getiobjectarg PyArg_GetObject getishortarg PyArg_GetShort getishortarray PyArg_GetShortArray getishortarraysize PyArg_GetShortArraySize getistringarg PyArg_GetString # mknewcharobject (replaced by mkvalue("c", ...)) # --- Error handling --- # (The 'Set' versions have an argument giving the exception type, # the others don't) err_badarg PyErr_BadArgument err_badcall PyErr_BadInternalCall err_input PyErr_Input err_nomem PyErr_NoMemory err_errno PyErr_SetFromErrno err_set PyErr_SetNone err_setstr PyErr_SetString err_setval PyErr_SetObject err_occurred PyErr_Occurred err_get PyErr_GetAndClear err_clear PyErr_Clear # --- Operating system dependent code --- fgets_intr PyOS_InterruptableGetString initintr PyOS_InitInterrupts intrcheck PyOS_InterruptOccurred getmtime PyOS_GetLastModificationTime --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Wed, 07 Jul 1993 10:13:05 +0200 Replied: "Bill McKinnon <mckinnon@ctron.com> " Received: from nic.near.net by charon.cwi.nl with SMTP id AA11121 (5.65b/3.8/CWI-Amsterdam); Tue, 6 Jul 1993 23:02:20 +0200 Received: from ctron.com by nic.near.net id aa24063; 6 Jul 93 17:02 EDT Received: from stealth.ctron.com ([134.141.6.107]) by ctron.com (4.1/SMI-4.1) id AA01511; Tue, 6 Jul 93 17:02:04 EDT Received: from express.ctron by stealth.ctron.com (4.1/SMI-4.1) id AA19548; Tue, 6 Jul 93 17:01:53 EDT Received: from pinto.ctron by express.ctron (4.1/SMI-4.1) id AA26376; Tue, 6 Jul 93 17:00:24 EDT Date: Tue, 6 Jul 93 17:00:24 EDT From: Bill McKinnon <mckinnon@ctron.com> Message-Id: <9307062100.AA26376@express.ctron> To: python-list@cwi.nl Subject: commercial users? We are currently looking at Python. It would be used as an embedded interpreter in a product. The product would require "non-programmers" to write Python. I am looking for opinions about Pythons ease-of-use. Any commercial success stories would also be helpful. Thanks in advance. Bill McKinnon Replied: Thu, 08 Jul 1993 18:27:52 +0200 Replied: "python-list@cwi.nl " Replied: Thu, 08 Jul 1993 13:07:50 +0200 Replied: "Jaap Vermeulen <jaap@sequent.com> " Replied: Thu, 08 Jul 1993 10:31:47 +0200 Replied: "Jaap Vermeulen <jaap@sequent.com> python-list@cwi.nl" Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA11241 (5.65b/3.8/CWI-Amsterdam); Wed, 7 Jul 1993 23:46:05 +0200 Received: from eng2.sequent.com by gateway.sequent.com (5.61/1.34) id AA03562; Wed, 7 Jul 93 14:46:54 -0700 Received: by eng2.sequent.com (5.65/1.34) id AA14590; Wed, 7 Jul 93 14:45:53 -0700 Message-Id: <9307072145.AA14590@eng2.sequent.com> To: python-list@cwi.nl Subject: strop module and whitespace Priority: Normal Precedence: first-class Organization: Sequent Computer Systems, Inc. Service Technology - MailStop: WIL2-610 15450 S.W. Koll Parkway Beaverton, OR 97006-6063 X-Phone: (503) 578-4404 X-Fax: (503) 578-4540 X-Uucp: ...!uunet!sequent!jaap X-Internet: jaap@sequent.com X-Face: C4Cnai$>Eja5I6Vq?(gdN#SXX#`-XgAnmUn&e54sx7@1>q@vkrd_XnH![P>w.:7IJJ;{Bts WJd)u&G!V}0OR?2o5cUgIY}.T{g]PMC=*~]3n_t)S-ZkC(WG}3:#hcA6Oazx:}yc&k,hsF7D},7x>l nyfRjO7$@]fHBN>aC9-M3pKfbYHiy!PWD{_bx~fo})b4tU.;Ao%x[upCI, Date: Wed, 07 Jul 93 14:45:52 PDT From: Jaap Vermeulen <jaap@sequent.com> I have two questions: 1) why is \r not considered whitespace? 2) even if I fix whitespace in string.py, it is not being picked up because it has been hardcoded in module strop to be space, \t and \n. (string.py imports strop.) Thanks, -Jaap- -- Jaap Vermeulen +--------------------------+ | Sequent Computer Systems | Internet : jaap@sequent.com | Beaverton, Oregon | Uucp : ...uunet!sequent!jaap +--------------------------+ Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA04329 (5.65b/3.8/CWI-Amsterdam); Thu, 8 Jul 1993 10:31:49 +0200 Received: by voorn.cwi.nl with SMTP id AA05505 (5.65b/3.8/CWI-Amsterdam); Thu, 8 Jul 1993 10:31:48 +0200 Message-Id: <9307080831.AA05505=guido@voorn.cwi.nl> To: Jaap Vermeulen <jaap@sequent.com> Cc: python-list@cwi.nl Subject: Re: strop module and whitespace In-Reply-To: Your message of "Wed, 07 Jul 1993 14:45:52 MDT." <9307072145.AA14590@eng2.sequent.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Thu, 08 Jul 1993 10:31:47 +0200 Sender: Guido.van.Rossum@cwi.nl > 1) why is \r not considered whitespace? Perhaps because \r is really a arbitrary control character (Python uses UNIX' convention that \n is the line separator). Or perhaps it's an oversight. What set of characters does ANSI C define to be whitespace? Should \f be added too? > 2) even if I fix whitespace in string.py, it is not being picked up > because it has been hardcoded in module strop to be space, \t and > \n. (string.py imports strop.) Same reason, and I thought it wasn't ever going to matter. Do you think it is sufficient if I fix this by adding \r (and \f) to the hardcoded list, or do you think we'll need a more general routine? A possibility, if people think this is worth it, would be to somehow find out which characters the C library's "isspace()" function considers whitespace and use this definition throughout. Feedback, please! --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from att-out.att.com by charon.cwi.nl with SMTP id AA10123 (5.65b/3.8/CWI-Amsterdam); Thu, 8 Jul 1993 12:25:18 +0200 From: hzsbg01!jbuhrma@hvgtw.att.com Received: from hzsbc03 by hzsbg01 (4.1/SMI-4.1) id AA22295; Thu, 8 Jul 93 12:17:33 +0200 Date: Thu, 8 Jul 93 12:17:33 +0200 Original-From: hzsbg01!jbuhrma Message-Id: <9307081017.AA22295@hzsbg01> To: Guido.van.Rossum@cwi.nl Subject: Re: strop module and whitespace > Perhaps because \r is really a arbitrary control character (Python > uses UNIX' convention that \n is the line separator). Or perhaps it's > an oversight. What set of characters does ANSI C define to be > whitespace? Should \f be added too? Yes, and don't forget the Vertical Tab. I don't have any standards at hand, but a simple program compiled on SunOS Release 4.1.3 (together with data from ``man ascii'' and A2.5.2 from K&R's C manual (ANSI version)) gives the following result: HT ^I '\t' (0011) isspace NL (LF) ^J '\n' (0012) isspace VT ^K '\v' (0013) isspace NP (FF) ^L '\f' (0014) isspace CR ^M '\r' (0015) isspace SP ' ' (0040) isspace Can't strop use the ctype functions? At least Python will behave then exactly like a C program would do. You could perhaps string.py be automatically generated from a C program that reflects that same ``local taste'' (if it would differ anyways from what's defined in some standard). > Feedback, please! Here you are... -- Jan-Hein Buhrman -- AT&T Huizen NL -- <jbuhrma%hzsbg01@hvlpa.att.com> -- ---------------------- +31 35 87.4278 --- ...!att!hvlpa!hzsbg01!jbuhrma --- ``There is a severe danger that we might finish the program today'' Received: from srv01s4.cas.org by charon.cwi.nl with SMTP id AA12517 (5.65b/3.8/CWI-Amsterdam); Thu, 8 Jul 1993 13:29:58 +0200 Date: Thu, 8 Jul 93 07:29:50 EDT From: jcv26@cas.org (Jon Vander Hill) Message-Id: <9307081129.AA28405@cas.org> To: Guido.van.Rossum@cwi.nl Subject: Re: strop module and whitespace In-Reply-To: <9307080831.AA05505=guido@voorn.cwi.nl> References: <9307072145.AA14590@eng2.sequent.com> <9307080831.AA05505=guido@voorn.cwi.nl> >>>>> On Thu, 08 Jul 1993 10:31:47 +0200, Guido.van.Rossum@cwi.nl said: >> 1) why is \r not considered whitespace? > Perhaps because \r is really a arbitrary control character (Python > uses UNIX' convention that \n is the line separator). Or perhaps it's > an oversight. What set of characters does ANSI C define to be > whitespace? Should \f be added too? >> 2) even if I fix whitespace in string.py, it is not being picked up >> because it has been hardcoded in module strop to be space, \t and >> \n. (string.py imports strop.) > Same reason, and I thought it wasn't ever going to matter. Do you > think it is sufficient if I fix this by adding \r (and \f) to the > hardcoded list, or do you think we'll need a more general routine? > A possibility, if people think this is worth it, would be to somehow > find out which characters the C library's "isspace()" function > considers whitespace and use this definition throughout. > Feedback, please! In C source files, ANSI C defines whitespace to include tab (0x09), newline (0x0a), vertical tab (0x0b), formfeed (0x0c), carriage return (0x0d), space (0x20), and comments. I don't have doc on the ANSI C library routines. The SunOS (non-ANSI) isspace() says all of the above (except comments) are whitespace. Jon Vander Hill jon@cas.org Received: from sun2.mhs-relay.ac.uk by charon.cwi.nl with SMTP id AA14883 (5.65b/3.8/CWI-Amsterdam); Thu, 8 Jul 1993 14:30:30 +0200 Via: uk.ac.oxford.prg; Thu, 8 Jul 1993 13:29:56 +0100 Received: from uk.ac.oxford.robots (lucrece-gate.robots) by prg.oxford.ac.uk id AA15947; Thu, 8 Jul 93 13:29:50 +0100 Received: from robots.ox.ac.uk (miranda.robots) by uk.ac.oxford.robots (4.1/robots.1) id AA06273; Thu, 8 Jul 93 13:29:48 BST Received: by robots.ox.ac.uk (4.1/robots.remoteV2.0) id AA15603; Thu, 8 Jul 93 13:29:47 BST Date: Thu, 8 Jul 93 13:29:47 BST From: peter@robots.oxford.ac.uk Message-Id: <9307081229.AA15603@miranda.robots.ox.ac.uk> To: Guido.van.Rossum@cwi.nl Subject: Re: strop module and whitespace Cc: python-list@cwi.nl Guido writes: > A possibility, if people think this is worth it, would be to somehow > find out which characters the C library's "isspace()" function > considers whitespace and use this definition throughout. > > Feedback, please! > > --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> > I think you could either have some kind of python variable (like sh's IFS) or as you suggest just use the C isspace() function. Both of these are an improvement on the current hardcoded behaviour, especially if python has the ability of running on multiple platforms. Pete. Received: from ohmg.hydro.on.ca by charon.cwi.nl with SMTP id AA17763 (5.65b/3.8/CWI-Amsterdam); Thu, 8 Jul 1993 15:43:04 +0200 Received: from eagle.hydro.on.ca by ohmg.hydro.on.ca with SMTP id <66998>; Thu, 8 Jul 1993 09:47:57 -0400 Received: by eagle.hydro.on.ca (4.1/SMI-4.1) id AA21575; Thu, 8 Jul 93 09:42:03 EDT Received: from thor.rd.hydro.on.ca by ohrd.rd.hydro.on.ca with SMTP id AA16527 (5.65c/IDA-1.4.4 for Guido.van.Rossum@cwi.nl); Thu, 8 Jul 1993 09:52:37 -0400 Received: by thor.rd.hydro.on.ca id AA24280 (5.65c/IDA-1.4.4 for python-list@cwi.nl); Thu, 8 Jul 1993 09:44:10 -0400 Date: Thu, 8 Jul 1993 09:44:10 -0400 From: Martin Green <martin.a.green@hydro.on.ca> Message-Id: <199307081344.AA24280@thor.rd.hydro.on.ca> To: Guido.van.Rossum@cwi.nl Cc: python-list@cwi.nl Subject: Re: strop module and whitespace In-Reply-To: <9307080831.AA05505=guido@voorn.cwi.nl> References: <9307072145.AA14590@eng2.sequent.com> <9307080831.AA05505=guido@voorn.cwi.nl> On July 8 at 04:31:47 you (Guido.van.Rossum@cwi.nl) wrote: > > A possibility, if people think this is worth it, would be to somehow > find out which characters the C library's "isspace()" function > considers whitespace and use this definition throughout. > > Feedback, please! The following program returns 9, 10, 11, 12, 13, 32 with SunOS 4.1.1. I would suggest using these as defaults in a string of whitespace characters that users can reassign if they want different behaviour. ======================================================================== #include <stdio.h> #include <ctype.h> main() { int i; for (i = 0; i < 256; i++) { if (isspace(i)) printf("%d\n", i); } } ======================================================================== Martin Green Net : green@rd.hydro.on.ca Ontario Hydro Research Division Tel : (416) 207-5745 800 Kipling Ave, KR260 FAX : (416) 207-5622 Toronto, Ontario, CANADA, M8Z5S4 Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA24258 (5.65b/3.8/CWI-Amsterdam); Thu, 8 Jul 1993 18:27:54 +0200 Received: by voorn.cwi.nl with SMTP id AA07059 (5.65b/3.8/CWI-Amsterdam); Thu, 8 Jul 1993 18:27:53 +0200 Message-Id: <9307081627.AA07059=guido@voorn.cwi.nl> To: python-list@cwi.nl Subject: Re: strop module and whitespace In-Reply-To: Your message of "Wed, 07 Jul 1993 14:45:52 MDT." <9307072145.AA14590@eng2.sequent.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Thu, 08 Jul 1993 18:27:53 +0200 Sender: Guido.van.Rossum@cwi.nl Thanks for the feedback. Now if everybody would also mail me their opinion on the subject of the GREAT RENAMING... I've chosen the following solution. In the next release of Python, the built-in module "strop" will export three variables: 'whitespace', 'lowercase' and 'uppercase', constructing by testing isspace(), islower() and isupper() for all characters in the range 1-255. These variables are inherited by the library module "string" (and its value of 'digits' is correctly calculated). I won't support changing these variables to modify the effect of the corresponding built-in functions (strip(), split(), lower(), upper() and swapcase()), since it would slow down their implementation considerably -- they currently use the macros defined in <ctype.h>. Of course the implementation could be made more efficient without losing flexibility, but I personally doubt the usefulness of the feature (especially since the effect would be global!), and I would prefer to keep it small and simple. If you need to have a version of split() that uses a different set of characters, perhaps you can use regsub.split() instead -- it uses a compiled regular expression for reasonable efficiency. I might be convinced that Python can use equivalents of strpbrk(), strspn(), strcspn() and strtok() though (any other favorite string ops?). --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> To: python-list@cwi.nl Subject: Re: strop module and whitespace In-reply-to: Your message of "Wed, 07 Jul 1993 14:45:52 MDT." <9307072145.AA14590@eng2.sequent.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Thu, 08 Jul 1993 18:27:53 +0200 Sender: guido Thanks for the feedback. Now if everybody would also mail me their opinion on the subject of the GREAT RENAMING... I've chosen the following solution. In the next release of Python, the built-in module "strop" will export three variables: 'whitespace', 'lowercase' and 'uppercase', constructing by testing isspace(), islower() and isupper() for all characters in the range 1-255. These variables are inherited by the library module "string" (and its value of 'digits' is correctly calculated). I won't support changing these variables to modify the effect of the corresponding built-in functions (strip(), split(), lower(), upper() and swapcase()), since it would slow down their implementation considerably -- they currently use the macros defined in <ctype.h>. Of course the implementation could be made more efficient without losing flexibility, but I personally doubt the usefulness of the feature (especially since the effect would be global!), and I would prefer to keep it small and simple. If you need to have a version of split() that uses a different set of characters, perhaps you can use regsub.split() instead -- it uses a compiled regular expression for reasonable efficiency. I might be convinced that Python can use equivalents of strpbrk(), strspn(), strcspn() and strtok() though (any other favorite string ops?). --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA25344 (5.65b/3.8/CWI-Amsterdam); Thu, 8 Jul 1993 18:49:32 +0200 To: Guido.van.Rossum@cwi.nl Cc: jaap@sequent.com, python-list@cwi.nl In-Reply-To: <9307080831.AA05505=guido@voorn.cwi.nl> (Guido.van.Rossum@cwi.nl) Subject: Re: strop module and whitespace Date: Thu, 8 Jul 93 9:48:30 PDT From: lance@markv.com Sender: lance@markv.com Message-Id: <9307080948.aa27197@hermix.markv.com> Source-Info: From (or Sender) name not authenticated. > 1) why is \r not considered whitespace? Perhaps because \r is really a arbitrary control character (Python uses UNIX' convention that \n is the line separator). Or perhaps it's an oversight. What set of characters does ANSI C define to be whitespace? Should \f be added too? > 2) even if I fix whitespace in string.py, it is not being picked up > because it has been hardcoded in module strop to be space, \t and > \n. (string.py imports strop.) Same reason, and I thought it wasn't ever going to matter. Do you think it is sufficient if I fix this by adding \r (and \f) to the hardcoded list, or do you think we'll need a more general routine? A possibility, if people think this is worth it, would be to somehow find out which characters the C library's "isspace()" function considers whitespace and use this definition throughout. Feedback, please! Why not have the module at import time scan the ascii table and use isspace() to find out the actual white space characters.. This would not take much time and would only be done with the first instance of the imported module. This will make it 100% machine independent. Comments? Lance Ellinghouse lance@markv.com Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA25481 (5.65b/3.8/CWI-Amsterdam); Thu, 8 Jul 1993 18:55:41 +0200 To: Guido.van.Rossum@cwi.nl In-Reply-To: <9307081627.AA07059=guido@voorn.cwi.nl> (Guido.van.Rossum@cwi.nl) Subject: Re: strop module and whitespace Date: Thu, 8 Jul 93 9:54:38 PDT From: lance@markv.com Sender: lance@markv.com Message-Id: <9307080954.aa27547@hermix.markv.com> Source-Info: From (or Sender) name not authenticated. I might be convinced that Python can use equivalents of strpbrk(), strspn(), strcspn() and strtok() though (any other favorite string ops?). I could use the strtok() function myself.. not sure about the rest though.. Lance Ellinghouse lance@markv.vom Replied: Thu, 29 Jul 1993 08:57:03 +0200 Replied: "python-list@cwi.nl " Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA06874 (5.65b/3.8/CWI-Amsterdam); Thu, 29 Jul 1993 05:04:27 +0200 From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: python-list@cwi.nl Subject: How to tell if in a script... Date: Wed, 28 Jul 93 20:03:55 PDT Message-Id: <9307282003.aa08579@hermix.markv.com> Is there a way to tell from inside a module if you are in an import statement or loading from a script? I have a .py file that can be loaded via 'import' or run from the command line.. Also, is there a way to tell if this module is loaded for the first time or if it is being reloaded via 'reload'??? I have a couple modules that MUST save state from import to reload. -- Lance Ellinghouse lance@markv.com 1231 bit key fingerprint = 56 DA 31 0C 17 51 36 6A 4E D4 E0 11 D9 B8 06 0A 1024 bit key fingerprint = 66 2C 75 F2 E9 1C 32 84 3A E3 B0 5E 48 01 4C 37 You can recieve my Public Key by `finger lance@mark.com` Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA08552 (5.65b/3.8/CWI-Amsterdam); Thu, 29 Jul 1993 08:57:04 +0200 Received: by voorn.cwi.nl with SMTP id AA09070 (5.65b/3.8/CWI-Amsterdam); Thu, 29 Jul 1993 08:57:04 +0200 Message-Id: <9307290657.AA09070=guido@voorn.cwi.nl> To: python-list@cwi.nl Subject: Re: How to tell if in a script... In-Reply-To: Your message of "Wed, 28 Jul 1993 20:03:55 MDT." <9307282003.aa08579@hermix.markv.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Thu, 29 Jul 1993 08:57:03 +0200 Sender: Guido.van.Rossum@cwi.nl Lance Ellinghouse: > Is there a way to tell from inside a module if you are in an import > statement or loading from a script? One trick that works: running_as_script = 0 xxx = [] # create a unique object import __main__ # the toplevel script being run try: if __main__.xxx is xxx: running_as_script = 1 except AttributeError: pass Note the use of 'is' for the comparison, this compares object identities instead of values. Essentially the same code can be used for testing whether you have been imported before (and hence are now being reloaded), by moving the assignment to xxx after the try..except block (and changing the name of the Boolean to something more meaningful, like impoerted_before). Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA24172 (5.65b/3.8/CWI-Amsterdam); Thu, 29 Jul 1993 16:57:16 +0200 Received: by voorn.cwi.nl with SMTP id AA17753 (5.65b/3.8/CWI-Amsterdam); Thu, 29 Jul 1993 16:57:16 +0200 Message-Id: <9307291457.AA17753=guido@voorn.cwi.nl> To: python-list@cwi.nl Subject: Python 0.9.9 is out! From: Guido.van.Rossum@cwi.nl X-Organization: CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Thu, 29 Jul 1993 16:57:15 +0200 Sender: Guido.van.Rossum@cwi.nl The subject says it all: I've finally gotten the courage to release Python 0.9.9. For the most part, it's as rock solid as previous releases. It also contains direct X11 support (Xt, with a choice between Athena or Motif widgets); however, that part of the release should be considered beta software. Ftp availability: ftp.cwi.nl:/pub/python; read the file INDEX for details. Files with "0.9.9" in them are obvious candidates for retrieval :-). There is also a Mac binary (no time to add the cute "16 tons" icon alas). I'm afraid there's no MS-DOS binary yet. Some highlights: * __init__ and __del__ methods to initialize and destroy class instances * more command line options, better usage message * no need to use \ for continuation lines within matching brackets * improved python-mode.el for Emacs * sprintf-like functionality using 'formatstring' % (var1, var2, ...) * dictionary keys can be other types than strings * array data type (mutable sequence of fixed-size numbers) * C-like functions for time conversions in module time: localtime, asctime, mktime etc. * Support for creating stand-alone executable binaries from Python scripts CAVEAT: I will be away for 7 weeks starting August 2; problems with the distribution are best discussed on the mailing list. --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from alpha.Xerox.COM by charon.cwi.nl with SMTP id AA01013 (5.65b/3.8/CWI-Amsterdam); Thu, 29 Jul 1993 19:45:33 +0200 Received: from eros.EuroPARC.Xerox.COM ([13.1.252.143]) by alpha.xerox.com with SMTP id <11629>; Thu, 29 Jul 1993 10:45:11 PDT Received: by eros.EuroPARC.Xerox.COM with SMTP (5.65c/IDA-1.2.9) id AA05034; Thu, 29 Jul 1993 18:44:09 +0100 Message-Id: <199307291744.AA05034@eros.EuroPARC.Xerox.COM> To: Guido.van.Rossum@cwi.nl Cc: python-list@cwi.nl Subject: Re: Python 0.9.9 is out! In-Reply-To: Your message of "Thu, 29 Jul 93 07:57:15 PDT." <9307291457.AA17753=guido@voorn.cwi.nl> Date: Thu, 29 Jul 1993 10:44:06 PDT From: Fraser@europarc.xerox.com Well, it built smoothly for me (on a sun) except: * It did need X11R5 to build the X stuff * stdwinmodule.c I think refers to a new stdwin? It didn't know what a BITMAP was, nor about the calls: _wsetwinpos _wsetwinsize _wlistfontnames I bypassed these bits and it built OK. Great Stuff! Quentin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Quentin Stafford-Fraser Tel: +44 223 341521 Rank Xerox EuroPARC, Fax: +44 223 341510 61 Regent Street, Home: +44 223 324451 Cambridge, CB2 1AB United Kingdom Fraser@europarc.xerox.com Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA09931 (5.65b/3.8/CWI-Amsterdam); Thu, 29 Jul 1993 23:06:24 +0200 From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: python-list@cwi.nl Subject: diffs for socketmodule.c Date: Thu, 29 Jul 93 14:06:04 PDT Message-Id: <9307291406.aa17594@hermix.markv.com> To get python0.9.9 to compile I have had to make a number of changes.. I am compiling under SCO ODT 2.0 and I will send the changes as I make them.. the first set is to socketmodule.c. Basicly SCO has no idea about AF_UNIX. Thus I remove ALL instances of AF_UNIX with "#ifndef M_UNIX". Here are the diffs... -- Lance Ellinghouse lance@markv.com 1231 bit key fingerprint = 56 DA 31 0C 17 51 36 6A 4E D4 E0 11 D9 B8 06 0A 1024 bit key fingerprint = 66 2C 75 F2 E9 1C 32 84 3A E3 B0 5E 48 01 4C 37 You can recieve my Public Key by `finger lance@mark.com` ==== Diffs 81d80 < #ifndef M_UNIX 83d81 < #endif 238d235 < #ifndef M_UNIX 244d240 < #endif 270d265 < #ifndef M_UNIX 288d282 < #endif 327d320 < #ifndef M_UNIX 333d325 < #endif 1071d1062 < #ifndef M_UNIX 1073d1063 < #endif Replied: Fri, 30 Jul 1993 10:23:20 +0200 Replied: "Jaap Vermeulen <jaap@sequent.com> python-list" Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA21218 (5.65b/3.8/CWI-Amsterdam); Fri, 30 Jul 1993 02:03:23 +0200 Received: from eng2.sequent.com by gateway.sequent.com (5.61/1.34) id AA17241; Thu, 29 Jul 93 17:00:09 -0700 Received: by eng2.sequent.com (5.65/1.34) id AA20780; Thu, 29 Jul 93 17:03:12 -0700 Message-Id: <9307300003.AA20780@eng2.sequent.com> To: python-list@cwi.nl Subject: Why does only sgi have DO_PG in posixmodule.c Priority: Normal Precedence: first-class Organization: Sequent Computer Systems, Inc. Service Technology - MailStop: WIL2-610 15450 S.W. Koll Parkway Beaverton, OR 97006-6063 X-Phone: (503) 578-4404 X-Fax: (503) 578-4540 X-Uucp: ...!uunet!sequent!jaap X-Internet: jaap@sequent.com X-Face: C4Cnai$>Eja5I6Vq?(gdN#SXX#`-XgAnmUn&e54sx7@1>q@vkrd_XnH![P>w.:7IJJ;{Bts WJd)u&G!V}0OR?2o5cUgIY}.T{g]PMC=*~]3n_t)S-ZkC(WG}3:#hcA6Oazx:}yc&k,hsF7D},7x>l nyfRjO7$@]fHBN>aC9-M3pKfbYHiy!PWD{_bx~fo})b4tU.;Ao%x[upCI, Date: Thu, 29 Jul 1993 17:03:10 -0700 From: Jaap Vermeulen <jaap@sequent.com> At the top of the file it sez: #ifdef __sgi #define DO_PG #endif Guess what, these process group commands come in handy, especially if you want to create a daemon (setsid). Actually, you can't create a daemon without those routines. Can't we include them by default? As a side issue, does python still print to stderr internally, no matter what you set sys.stderr to? That is very annoying if you try to make it shut up completely. Thanks, -Jaap- -- Jaap Vermeulen +--------------------------+ | Sequent Computer Systems | Internet : jaap@sequent.com | Beaverton, Oregon | Uucp : ...uunet!sequent!jaap +--------------------------+ Replied: Fri, 30 Jul 1993 10:28:49 +0200 Replied: "Jaap Vermeulen <jaap@sequent.com> python-list@cwi.nl" Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA22223 (5.65b/3.8/CWI-Amsterdam); Fri, 30 Jul 1993 02:10:35 +0200 Received: from eng2.sequent.com by gateway.sequent.com (5.61/1.34) id AA17445; Thu, 29 Jul 93 17:07:26 -0700 Received: by eng2.sequent.com (5.65/1.34) id AA22662; Thu, 29 Jul 93 17:10:27 -0700 Message-Id: <9307300010.AA22662@eng2.sequent.com> To: python-list@cwi.nl Subject: The new freeze code Priority: Normal Precedence: first-class Organization: Sequent Computer Systems, Inc. Service Technology - MailStop: WIL2-610 15450 S.W. Koll Parkway Beaverton, OR 97006-6063 X-Phone: (503) 578-4404 X-Fax: (503) 578-4540 X-Uucp: ...!uunet!sequent!jaap X-Internet: jaap@sequent.com X-Face: C4Cnai$>Eja5I6Vq?(gdN#SXX#`-XgAnmUn&e54sx7@1>q@vkrd_XnH![P>w.:7IJJ;{Bts WJd)u&G!V}0OR?2o5cUgIY}.T{g]PMC=*~]3n_t)S-ZkC(WG}3:#hcA6Oazx:}yc&k,hsF7D},7x>l nyfRjO7$@]fHBN>aC9-M3pKfbYHiy!PWD{_bx~fo})b4tU.;Ao%x[upCI, Date: Thu, 29 Jul 1993 17:10:26 -0700 From: Jaap Vermeulen <jaap@sequent.com> I tried it: very nifty indeed. However, it seems like I get dumped into the interpreter after the the script is done running. I tried the script freeze.py on the script dutree.py. Is this intentional, or is something wrong? As a side comment, it's better to use 'unsigned char' for 8 bit code, so that the ansi compiler doesn't complain all the time about '"./frozen.c", line x: warning: initializer does not fit: xxx'. print 'static unsigned char M_' + mod + '[' + \ ^^^^^^^^ and print ' unsigned char *code;' ^^^^^^^^ (the ^^^ piece is proposed). Thanks, -Jaap- -- Jaap Vermeulen +--------------------------+ | Sequent Computer Systems | Internet : jaap@sequent.com | Beaverton, Oregon | Uucp : ...uunet!sequent!jaap +--------------------------+ Replied: Fri, 30 Jul 1993 10:36:49 +0200 Replied: "lance@markv.com python-list@cwi.nl" Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA23770 (5.65b/3.8/CWI-Amsterdam); Fri, 30 Jul 1993 02:20:36 +0200 To: python-list@cwi.nl Subject: revised import.c Date: Thu, 29 Jul 93 17:20:04 PDT From: lance@markv.com Sender: lance@markv.com Message-Id: <9307291720.aa01937@hermix.markv.com> Source-Info: From (or Sender) name not authenticated. I have merged my changes to import.c into the 0.9.9 version. Here are the diffs for the 0.9.9 version that allow you to have a .pyc file without the .py file being present. Again, this still needs to be tested by someone that uses dynamic linking as I don't. Enjoy! *** import.c Tue May 25 02:38:24 1993 --- import.c.new Thu Jul 29 17:10:14 1993 *************** *** 38,45 **** --- 38,56 ---- #include "eval.h" #include "osdefs.h" + #include <unistd.h> + #include <sys/stat.h> + extern int verbose; /* Defined in pythonmain.c */ + #ifndef FALSE + #define FALSE 0 + #endif + + #ifndef TRUE + #define TRUE 1 + #endif + #ifdef DEBUG #define D(x) x #else *************** *** 97,137 **** /* Suffixes used by open_module: */ #define PY_SUFFIX ".py" #ifdef USE_DL #define O_SUFFIX "module.o" #endif ! /* Find and open a module file, using sys.path. ! Return a NULL pointer if no module file is found. ! When dynamic loading is enabled, the contents of namebuf ! is important when NULL is returned: if namebuf[0] != '\0' ! a dl-able object file was found and namebuf is its pathname. */ ! ! static FILE * ! open_module(name, namebuf) char *name; ! char *namebuf; /* XXX No buffer overflow checks! */ { object *path; ! FILE *fp; ! path = sysget("path"); if (path == NULL || !is_listobject(path)) { /* No path -- at least try current directory */ - #ifdef USE_DL - strcpy(namebuf, name); - strcat(namebuf, O_SUFFIX); - if (getmtime(namebuf) > 0) - return NULL; - #endif strcpy(namebuf, name); ! strcat(namebuf, PY_SUFFIX); ! fp = fopen(namebuf, "r"); ! } ! else { int npath = getlistsize(path); int i; - fp = NULL; for (i = 0; i < npath; i++) { object *v = getlistitem(path, i); int len; --- 108,146 ---- /* Suffixes used by open_module: */ #define PY_SUFFIX ".py" + #define PYC_SUFFIX ".pyc" #ifdef USE_DL #define O_SUFFIX "module.o" #endif ! /* This will search for a module named 'name' with the extension 'ext' ! and return it in 'namebuf' and return the mtime of each in 'mtime' ! it will return TRUE if it found it, FALSE if it does not. ! */ ! static int ! find_module(name, ext, namebuf, mtime) char *name; ! char *ext; ! char *namebuf; ! time_t *mtime; { object *path; ! struct stat s; ! path = sysget("path"); if (path == NULL || !is_listobject(path)) { /* No path -- at least try current directory */ strcpy(namebuf, name); ! strcat(namebuf, ext); ! if (stat(namebuf,&s) == -1) ! return FALSE; ! if (access(namebuf,R_OK) == -1) ! return FALSE; ! *mtime = s.st_mtime; ! return TRUE; ! } else { int npath = getlistsize(path); int i; for (i = 0; i < npath; i++) { object *v = getlistitem(path, i); int len; *************** *** 141,162 **** len = getstringsize(v); if (len > 0 && namebuf[len-1] != SEP) namebuf[len++] = SEP; - #ifdef USE_DL strcpy(namebuf+len, name); ! strcat(namebuf, O_SUFFIX); ! if (getmtime(namebuf) > 0) ! return NULL; ! #endif ! strcpy(namebuf+len, name); ! strcat(namebuf, PY_SUFFIX); ! fp = fopen(namebuf, "r"); ! if (fp != NULL) ! break; } } ! if (fp == NULL) ! namebuf[0] = '\0'; ! return fp; } static object * --- 150,167 ---- len = getstringsize(v); if (len > 0 && namebuf[len-1] != SEP) namebuf[len++] = SEP; strcpy(namebuf+len, name); ! strcat(namebuf, ext); ! if (stat(namebuf,&s) == -1) ! continue; ! if (access(namebuf,R_OK) == -1) ! continue; ! *mtime = s.st_mtime; ! return TRUE; } } ! namebuf[0] = '\0'; ! return FALSE; } static object * *************** *** 175,183 **** long mtime; extern long getmtime(); ! fp = open_module(name, namebuf); ! if (fp == NULL) { #ifdef USE_DL if (namebuf[0] != '\0') { char funcname[258]; dl_funcptr p; --- 180,188 ---- long mtime; extern long getmtime(); ! #ifdef USE_DL + if (find_module(name,O_SUFFIX,namebuf,&mtime)) { if (namebuf[0] != '\0') { char funcname[258]; dl_funcptr p; *************** *** 186,193 **** p = dl_loadmod(argv0, namebuf, funcname); if (p == NULL) { D(fprintf(stderr, "dl_loadmod failed\n")); ! } ! else { if (verbose) fprintf(stderr, "import %s # dynamically loaded from \"%s\"\n", --- 191,197 ---- p = dl_loadmod(argv0, namebuf, funcname); if (p == NULL) { D(fprintf(stderr, "dl_loadmod failed\n")); ! } else { if (verbose) fprintf(stderr, "import %s # dynamically loaded from \"%s\"\n", *************** *** 198,205 **** err_setstr(SystemError, "dynamic module missing"); return NULL; ! } ! else { D(fprintf(stderr, "module %s loaded!\n", name)); INCREF(None); --- 202,208 ---- err_setstr(SystemError, "dynamic module missing"); return NULL; ! } else { D(fprintf(stderr, "module %s loaded!\n", name)); INCREF(None); *************** *** 207,213 **** --- 210,272 ---- } } } + } else #endif + if (find_module(name,PYC_SUFFIX,namebuf,&mtime)) { + read_pyc: + fpc = fopen(namebuf, "rb"); + namebuf[(strlen(namebuf)-1)] = '\0'; + mtime = getmtime(namebuf); + if (fpc != NULL) { + long pyc_mtime; + long magic; + magic = rd_long(fpc); + pyc_mtime = rd_long(fpc); + if (mtime != -1 && mtime > pyc_mtime) { + fclose(fpc); + goto read_py; + } + if (magic == MAGIC) { + v = rd_object(fpc); + if (v == NULL || err_occurred() || !is_codeobject(v)) { + err_clear(); + XDECREF(v); + } + else + co = (codeobject *)v; + } + fclose(fpc); + if (verbose) { + if (co != NULL) + fprintf(stderr, + "import %s # precompiled from \"%s\"\n", + name, namebuf); + else + fprintf(stderr, + "# invalid precompiled file \"%s\"\n", + namebuf); + } + } + } else if (find_module(name,PY_SUFFIX,namebuf,&mtime)) { + read_py: + fp = fopen(namebuf,"rb"); + namelen = strlen(namebuf); + if (co == NULL) { + if (verbose) + fprintf(stderr, + "import %s # from \"%s\"\n", + name, namebuf); + err = parse_file(fp, namebuf, file_input, &n); + } else + err = E_DONE; + fclose(fp); + if (err != E_DONE) { + err_input(err); + return NULL; + } + } else { if (m == NULL) { sprintf(namebuf, "no module named %.200s", name); err_setstr(ImportError, namebuf); *************** *** 216,269 **** sprintf(namebuf, "no source for module %.200s", name); err_setstr(ImportError, namebuf); } - return NULL; - } - /* Get mtime -- always useful */ - mtime = getmtime(namebuf); - /* Check ".pyc" file first */ - namelen = strlen(namebuf); - namebuf[namelen] = 'c'; - namebuf[namelen+1] = '\0'; - fpc = fopen(namebuf, "rb"); - if (fpc != NULL) { - long pyc_mtime; - long magic; - magic = rd_long(fpc); - pyc_mtime = rd_long(fpc); - if (magic == MAGIC && pyc_mtime == mtime && mtime != 0 && mtime != -1) { - v = rd_object(fpc); - if (v == NULL || err_occurred() || !is_codeobject(v)) { - err_clear(); - XDECREF(v); - } - else - co = (codeobject *)v; - } - fclose(fpc); - if (verbose) { - if (co != NULL) - fprintf(stderr, - "import %s # precompiled from \"%s\"\n", - name, namebuf); - else - fprintf(stderr, - "# invalid precompiled file \"%s\"\n", - namebuf); - } - } - namebuf[namelen] = '\0'; - if (co == NULL) { - if (verbose) - fprintf(stderr, - "import %s # from \"%s\"\n", - name, namebuf); - err = parse_file(fp, namebuf, file_input, &n); - } - else - err = E_DONE; - fclose(fp); - if (err != E_DONE) { - err_input(err); return NULL; } if (m == NULL) { --- 275,280 ---- -- Lance Ellinghouse lance@markv.com 1231 bit key fingerprint = 56 DA 31 0C 17 51 36 6A 4E D4 E0 11 D9 B8 06 0A 1024 bit key fingerprint = 66 2C 75 F2 E9 1C 32 84 3A E3 B0 5E 48 01 4C 37 You can recieve my Public Key by `finger lance@mark.com` Replied: Fri, 30 Jul 1993 10:40:14 +0200 Replied: "Lance Ellinghouse <lance@markv.com> python-list@cwi.nl" Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA00633 (5.65b/3.8/CWI-Amsterdam); Fri, 30 Jul 1993 07:51:22 +0200 From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: python-list@cwi.nl Subject: JPEG module.... Date: Thu, 29 Jul 93 22:51:04 PDT Message-Id: <9307292251.aa22355@hermix.markv.com> Where can I get the libraries needed for the JPEG module? Thanks! -- Lance Ellinghouse lance@markv.com 1231 bit key fingerprint = 56 DA 31 0C 17 51 36 6A 4E D4 E0 11 D9 B8 06 0A 1024 bit key fingerprint = 66 2C 75 F2 E9 1C 32 84 3A E3 B0 5E 48 01 4C 37 You can recieve my Public Key by `finger lance@mark.com` Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA06424 (5.65b/3.8/CWI-Amsterdam); Fri, 30 Jul 1993 10:23:22 +0200 Received: by voorn.cwi.nl with SMTP id AA18847 (5.65b/3.8/CWI-Amsterdam); Fri, 30 Jul 1993 10:23:21 +0200 Message-Id: <9307300823.AA18847=guido@voorn.cwi.nl> To: Jaap Vermeulen <jaap@sequent.com> Cc: python-list@cwi.nl Subject: Re: Why does only sgi have DO_PG in posixmodule.c In-Reply-To: Your message of "Thu, 29 Jul 1993 17:03:10 MDT." <9307300003.AA20780@eng2.sequent.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Fri, 30 Jul 1993 10:23:20 +0200 Sender: Guido.van.Rossum@cwi.nl > At the top of the file it sez: > > #ifdef __sgi > #define DO_PG > #endif > > Guess what, these process group commands come in handy, especially if > you want to create a daemon (setsid). Actually, you can't create a > daemon without those routines. Can't we include them by default? Not all systems support this, especially SunOS 4 doesn't. It should have been made a "Configure" time option. > As a side issue, does python still print to stderr internally, no > matter what you set sys.stderr to? That is very annoying if you try to > make it shut up completely. There is some output to stderr, but only if the interpreter gets seriously confused. Stack traces go to whatever sys.stderr points to. --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA06924 (5.65b/3.8/CWI-Amsterdam); Fri, 30 Jul 1993 10:36:52 +0200 Received: by voorn.cwi.nl with SMTP id AA18885 (5.65b/3.8/CWI-Amsterdam); Fri, 30 Jul 1993 10:36:50 +0200 Message-Id: <9307300836.AA18885=guido@voorn.cwi.nl> To: lance@markv.com Cc: python-list@cwi.nl Subject: Re: revised import.c In-Reply-To: Your message of "Thu, 29 Jul 1993 17:20:04 MDT." <9307291720.aa01937@hermix.markv.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Fri, 30 Jul 1993 10:36:49 +0200 Sender: Guido.van.Rossum@cwi.nl > I have merged my changes to import.c into the 0.9.9 version. > Here are the diffs for the 0.9.9 version that allow you to have > a .pyc file without the .py file being present. Again, this still > needs to be tested by someone that uses dynamic linking as I don't. I can see why you'd want this in certain cases, but when I designed this code I made a conscious decision to require that the .py should file be there for the .pyc file to be valid -- unlike Emacs .elc files, .pyc files can be considered as pure caches and are managed completely automatic. Perhaps Lance's version can be made into a compile-time or run-time option? --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA07056 (5.65b/3.8/CWI-Amsterdam); Fri, 30 Jul 1993 10:40:16 +0200 Received: by voorn.cwi.nl with SMTP id AA18904 (5.65b/3.8/CWI-Amsterdam); Fri, 30 Jul 1993 10:40:14 +0200 Message-Id: <9307300840.AA18904=guido@voorn.cwi.nl> To: Lance Ellinghouse <lance@markv.com> Cc: python-list@cwi.nl Subject: Re: JPEG module.... In-Reply-To: Your message of "Thu, 29 Jul 1993 22:51:04 MDT." <9307292251.aa22355@hermix.markv.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Fri, 30 Jul 1993 10:40:14 +0200 Sender: Guido.van.Rossum@cwi.nl > Where can I get the libraries needed for the JPEG module? Oops, I should have placed a pointer somewhere. From the README file of the jpeg code: |README for release of 7-Oct-91 |=============================== | |This distribution contains the first public release of the Independent JPEG |Group's free JPEG software. You are welcome to redistribute this software and |to use it for any purpose, subject to the conditions under LEGAL ISSUES, below | |This software is still undergoing revision. Updated versions may be obtained |by anonymous FTP to uunet.uu.net; look under directory /graphics/jpeg. This |particular version will be archived as jpegsrc.v1.tar.Z. If you don't have |access to Internet FTP, UUNET's archives are also available via UUCP; contact |postmaster@uunet.uu.net for information on retrieving files that way. | |Please report any problems with this software to jpeg-info@uunet.uu.net. I believe this isn't the latest but I expect that at least one of the mentioned locations or email addresses still works... --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from alpha.Xerox.COM by charon.cwi.nl with SMTP id AA07407 (5.65b/3.8/CWI-Amsterdam); Fri, 30 Jul 1993 10:48:17 +0200 Received: from eros.EuroPARC.Xerox.COM ([13.1.252.143]) by alpha.xerox.com with SMTP id <11600>; Fri, 30 Jul 1993 01:47:49 PDT Received: by eros.EuroPARC.Xerox.COM with SMTP (5.65c/IDA-1.2.9) id AA07971; Fri, 30 Jul 1993 09:47:14 +0100 Message-Id: <199307300847.AA07971@eros.EuroPARC.Xerox.COM> To: python-list@cwi.nl Subject: Bitmaps In-Reply-To: Your message of "Thu, 29 Jul 93 07:57:15 PDT." <9307291457.AA17753=guido@voorn.cwi.nl> Date: Fri, 30 Jul 1993 01:47:09 PDT From: Fraser@europarc.xerox.com Well, I read the NEWS file, and it said that you might need the version of stdwin for Views, so I got that, but it still doesn't seem to have the bitmap stuff that stdwinmodule is looking for. My hacked version seems to work ok, though, so I'll wait until Guido gets back. Talking of Guido, if, like me, you haven't met him and wonder what he looks like, tell xmosaic to open the CWI home page, which I found at ftp://ftp.cwi.nl/pub/www/default.html. If you don't have xmosaic, I strongly recommend that you get a copy! (from ftp.ncsa.uiuc.edu) Quentin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Quentin Stafford-Fraser Tel: +44 223 341521 Rank Xerox EuroPARC, Fax: +44 223 341510 61 Regent Street, Home: +44 223 324451 Cambridge, CB2 1AB United Kingdom Fraser@europarc.xerox.com Received: from schelvis.cwi.nl by charon.cwi.nl with SMTP id AA12390 (5.65b/3.8/CWI-Amsterdam); Fri, 30 Jul 1993 12:38:55 +0200 Received: by schelvis.cwi.nl with SMTP id AA02228 (5.65b/3.8/CWI-Amsterdam); Fri, 30 Jul 1993 12:38:55 +0200 Message-Id: <9307301038.AA02228=jack@schelvis.cwi.nl> To: python-list@cwi.nl Subject: JPEG in python Organisation: Multi-media group, CWI, Kruislaan 413, Amsterdam Phone: +31 20 5924098(work), +31 20 5924199 (fax), +31 20 6160335(home) X-Last-Band-Seen: Beat Busters, Desmond Dekker (Paradiso, 24-7) X-Mini-Review: Uptown top skanking! Date: Fri, 30 Jul 1993 12:38:54 +0200 From: Jack Jansen <Jack.Jansen@cwi.nl> Actually, the jpeg module in python needs my mucho-hacked-up version of a very old jpeg distribution. I had to hack in memory-to-memory conversion of jpeg data. (Hey, that's nice, the three 'jpeg's align nicely:-) I'll be gone for 10 days, but when I come back I'll try to whip something up with a newer jpeg version that is distributable. Note that people with SGI machines *can* use jpeg: there is a module with the same interface that uses the sgi compression library to compress/decompress jpeg images. -- Jack Jansen | If I can't dance I don't want to be part of Jack.Jansen@cwi.nl | your revolution -- Emma Goldman uunet!cwi.nl!jack G=Jack;S=Jansen;O=cwi;PRMD=surf;ADMD=400net;C=nl Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA16569 (5.65b/3.8/CWI-Amsterdam); Fri, 30 Jul 1993 14:13:16 +0200 Received: by voorn.cwi.nl with SMTP id AA21400 (5.65b/3.8/CWI-Amsterdam); Fri, 30 Jul 1993 14:13:14 +0200 Message-Id: <9307301213.AA21400=guido@voorn.cwi.nl> To: python-list@cwi.nl Subject: stdwin 0.9.8 released From: Guido.van.Rossum@cwi.nl X-Organization: CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Fri, 30 Jul 1993 14:13:14 +0200 Sender: Guido.van.Rossum@cwi.nl Well, it only took me 30 minutes to prepare a stdwin distribution that will actually work with the stdwinmodule.c from the Python 0.9.9 release. It can be picked up from the usual place: ftp.cwi.nl:/pub/stdwin/stdwin0.9.8.tar.Z Documentation is lacking as usual -- read stdwin.h and the source... --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Fri, 30 Jul 1993 20:34:57 +0200 Replied: "Jaap Vermeulen <jaap@sequent.com> python-list@cwi.nl" Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA29581 (5.65b/3.8/CWI-Amsterdam); Fri, 30 Jul 1993 18:49:30 +0200 Received: from eng2.sequent.com by gateway.sequent.com (5.61/1.34) id AA13017; Fri, 30 Jul 93 09:46:13 -0700 Received: by eng2.sequent.com (5.65/1.34) id AA09281; Fri, 30 Jul 93 09:49:16 -0700 Message-Id: <9307301649.AA09281@eng2.sequent.com> To: Guido.van.Rossum@cwi.nl Cc: python-list@cwi.nl Subject: Re: Why does only sgi have DO_PG in posixmodule.c Priority: Normal Precedence: first-class Organization: Sequent Computer Systems, Inc. Service Technology - MailStop: WIL2-610 15450 S.W. Koll Parkway Beaverton, OR 97006-6063 X-Phone: (503) 578-4404 X-Fax: (503) 578-4540 X-Uucp: ...!uunet!sequent!jaap X-Internet: jaap@sequent.com X-Face: C4Cnai$>Eja5I6Vq?(gdN#SXX#`-XgAnmUn&e54sx7@1>q@vkrd_XnH![P>w.:7IJJ;{Bts WJd)u&G!V}0OR?2o5cUgIY}.T{g]PMC=*~]3n_t)S-ZkC(WG}3:#hcA6Oazx:}yc&k,hsF7D},7x>l nyfRjO7$@]fHBN>aC9-M3pKfbYHiy!PWD{_bx~fo})b4tU.;Ao%x[upCI, In-Reply-To: Guido.van.Rossum@cwi.nl's message of Fri, 30 Jul 1993 10:23:20 +0200. <9307300823.AA18847=guido@voorn.cwi.nl> Date: Fri, 30 Jul 1993 09:49:15 -0700 From: Jaap Vermeulen <jaap@sequent.com> | There is some output to stderr, but only if the interpreter gets | seriously confused. Stack traces go to whatever sys.stderr points to. What about stderr output from posix.system() or posix.popen()? -Jaap- -- Jaap Vermeulen +--------------------------+ | Sequent Computer Systems | Internet : jaap@sequent.com | Beaverton, Oregon | Uucp : ...uunet!sequent!jaap +--------------------------+ Replied: Fri, 30 Jul 1993 20:32:50 +0200 Replied: "Jaap Vermeulen <jaap@sequent.com> " Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA29685 (5.65b/3.8/CWI-Amsterdam); Fri, 30 Jul 1993 18:52:16 +0200 Received: from eng2.sequent.com by gateway.sequent.com (5.61/1.34) id AA13103; Fri, 30 Jul 93 09:49:03 -0700 Received: by eng2.sequent.com (5.65/1.34) id AA09689; Fri, 30 Jul 93 09:52:06 -0700 Message-Id: <9307301652.AA09689@eng2.sequent.com> To: Fraser@europarc.xerox.com Cc: python-list@cwi.nl Subject: Re: Bitmaps Priority: Normal Precedence: first-class Organization: Sequent Computer Systems, Inc. Service Technology - MailStop: WIL2-610 15450 S.W. Koll Parkway Beaverton, OR 97006-6063 X-Phone: (503) 578-4404 X-Fax: (503) 578-4540 X-Uucp: ...!uunet!sequent!jaap X-Internet: jaap@sequent.com X-Face: C4Cnai$>Eja5I6Vq?(gdN#SXX#`-XgAnmUn&e54sx7@1>q@vkrd_XnH![P>w.:7IJJ;{Bts WJd)u&G!V}0OR?2o5cUgIY}.T{g]PMC=*~]3n_t)S-ZkC(WG}3:#hcA6Oazx:}yc&k,hsF7D},7x>l nyfRjO7$@]fHBN>aC9-M3pKfbYHiy!PWD{_bx~fo})b4tU.;Ao%x[upCI, In-Reply-To: Fraser@europarc.xerox.com's message of Fri, 30 Jul 1993 01:47:09 -0700. <199307300847.AA07971@eros.EuroPARC.Xerox.COM> Date: Fri, 30 Jul 1993 09:52:05 -0700 From: Jaap Vermeulen <jaap@sequent.com> | Talking of Guido, if, like me, you haven't met him and wonder what he | looks like, tell xmosaic to open the CWI home page, which I found at Who the hell want to know what Guido looks like (with his colorful glasses)!!! :-) :-) :-) :-) :-) :-) :-) -Jaap- -- Jaap Vermeulen +--------------------------+ | Sequent Computer Systems | Internet : jaap@sequent.com | Beaverton, Oregon | Uucp : ...uunet!sequent!jaap +--------------------------+ Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA04181 (5.65b/3.8/CWI-Amsterdam); Fri, 30 Jul 1993 20:34:58 +0200 Received: by voorn.cwi.nl with SMTP id AA23285 (5.65b/3.8/CWI-Amsterdam); Fri, 30 Jul 1993 20:34:58 +0200 Message-Id: <9307301834.AA23285=guido@voorn.cwi.nl> To: Jaap Vermeulen <jaap@sequent.com> Cc: python-list@cwi.nl Subject: Re: Why does only sgi have DO_PG in posixmodule.c In-Reply-To: Your message of "Fri, 30 Jul 1993 09:49:15 MDT." <9307301649.AA09281@eng2.sequent.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Fri, 30 Jul 1993 20:34:57 +0200 Sender: Guido.van.Rossum@cwi.nl > | There is some output to stderr, but only if the interpreter gets > | seriously confused. Stack traces go to whatever sys.stderr points to. > > What about stderr output from posix.system() or posix.popen()? Good question. Note that you can now use os.dup(), os.open(), os.close() etc. to manipulate file descriptors, so in principle it is possible, but I agree that fd's 0, 1, 2 should inherit from sys.stdin/out/err. (I'm afraid this addition never made the NEWS file... Check the ChangeLog file however; it's also in the library manual!) Next release, hopefully! --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA23163 (5.65b/3.8/CWI-Amsterdam); Sat, 31 Jul 1993 01:59:59 +0200 To: Guido.van.Rossum@cwi.nl Cc: jaap@sequent.com, python-list@cwi.nl In-Reply-To: <9307301834.AA23285=guido@voorn.cwi.nl> (Guido.van.Rossum@cwi.nl) Subject: Re: Why does only sgi have DO_PG in posixmodule.c Date: Fri, 30 Jul 93 16:58:54 PDT From: lance@markv.com Sender: lance@markv.com Message-Id: <9307301658.aa10696@hermix.markv.com> Source-Info: From (or Sender) name not authenticated. setting DO_PG for SCO ODT 2.0 works fine! Just wanted to let people know.. -- Lance Ellinghouse lance@markv.com 1231 bit key fingerprint = 56 DA 31 0C 17 51 36 6A 4E D4 E0 11 D9 B8 06 0A 1024 bit key fingerprint = 66 2C 75 F2 E9 1C 32 84 3A E3 B0 5E 48 01 4C 37 You can recieve my Public Key by `finger lance@mark.com` Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA24264 (5.65b/3.8/CWI-Amsterdam); Sat, 31 Jul 1993 02:09:51 +0200 To: python-list@cwi.nl Subject: replacement for nntpxmit.py Date: Fri, 30 Jul 93 17:08:51 PDT From: lance@markv.com Sender: lance@markv.com Message-Id: <9307301708.aa10911@hermix.markv.com> Source-Info: From (or Sender) name not authenticated. I got completely tired of nntpxmit dieing on my system so I thought I would rewrite it in Python.. Thanks to the new nntplib.py file in the 0.9.9 lib directory I was able to toss out about 200 lines of code that I had written and now have a nntpxmit.py file that works!! Here it is for any who wish it.. please let me know of any bugs or improvements.. Mind you there are almost NO comments in it.. have not had time to go through it and probably won't have time now that it is working.. #! /usr2/local/bin/python # This file reads the batch files created by NNTP and # sends the messages to the remote site. # The usage for this program is: # # nntpxmit Batch_dir News_dir import sys import strop import posix from nntplib import NNTP, error_temp, error_reply False = 0 True = 1 ##### # Global locations to use ##### NewsSpoolDir = '' NewsBatchDir = '' if len(sys.argv) != 3: print 'Usage: ' + sys.argv[0] + ' NNTP_Batch_Dir NEWS_Directory' raise SystemExit NewsSpoolDir = sys.argv[2] + '/' NewsBatchDir = sys.argv[1] + '/' NewsBatchHost= '' ##### # Codes returned from NNTP Server ##### OK_NOPOST = 201 OK_CANPOST = 200 OK_XFERD = 235 CONT_XFER = 335 ERR_GOTIT = 435 ERR_XFERRJCT = 437 ERR_XFERFAIL = 436 ##### # Globals ##### # Transfer Stats Stats = { 'offered':0, 'accepted':0, 'rejected':0, 'failed':0 } Debug = False Report_Stats = True ReQueue_fails = True Debug_Stream = None Requeue_Article_lst = [] ##### # Support Functions ##### def reset_stats(): global Stats Stats['offered'] = 0 Stats['accepted'] = 0 Stats['rejected'] = 0 Stats['failed'] = 0 return None def print_stats(host): global Stats print '' print 'Statistics for \'' + host + '\'' print '='*30 print 'Offered : ' + `Stats['offered']` print 'Accepted : ' + `Stats['accepted']` print 'Rejected : ' + `Stats['rejected']` print 'Failed : ' + `Stats['failed']` print '' return None def write_requeue(file_name, lst): try: fp = open(NewsBatchDir + file_name,'a+') except IOError, msg: print 'write_requeue(' + NewsBatchDir + file_name + ') failed: ' + msg return None if len(lst) == 0: fp.close() return None for item in lst: try: fp.write(item[0] + ' ' + item[1] + '\n') except IOError, msg: print 'write_requeue(' + NewsBatchDir + file_name + ') failed: ' + msg return None return None # This routine takes a file name and loads all the lines in the file # into a list. This list contains 2 parts, ('filename','message id') # This information is taked from a batch file def load_batch(file_name): try: fp = open(file_name,'r') except: return None list = [] list = fp.readlines() for ndx in range(len(list)): list_el = strop.strip(list[ndx]) l = len(list_el) j = 0 while j < l and list_el[j] != ' ': j = j + 1 fn = list_el[0:j] msgid = list_el[j:] list[ndx] = (strop.strip(fn),strop.strip(msgid)) try: t = posix.unlink(file_name) except: pass return list # this will lock a directory def lock_dir(dir_to_lock): t_dir = posix.getcwd() r = posix.chdir(dir_to_lock) try: r = open('.LCK'+`posix.getpid()`,'w') except: r = posix.chdir(t_dir) return False r.close() try: r = posix.link('.LCK'+`posix.getpid()`,'.LCKdir') except: r = posix.chdir(t_dir) return False r = posix.chdir(t_dir) return True # This will unlock the directory def unlock_dir(dir_to_unlock): t_dir = posix.getcwd() r = posix.chdir(dir_to_unlock) try: r = posix.unlink('.LCKdir') r = posix.unlink('.LCK'+`posix.getpid()`) except: return False r = posix.chdir(t_dir) return True # This function returns 2 lists.. # 1: A list of all files in the directory that are NOT requeue files (! '~xxx') # 2: A list of all files in the directory that are requeue files (~xxx) # This function NEVER returns files that start as '.LCK' as these # are lock files and Never need to be touched and it never returns # files that start with '.' as these are hidden def rtn_dirlist(dir_to_list): requeue_lst = [] rtn_lst = [] try: lst = posix.listdir(dir_to_list) except: return (None, None) for i in range(len(lst)): name = lst[i] if name[0] == '.': continue if name[0] == '~': r = requeue_lst.append(name) continue rtn_lst.append(name) return (rtn_lst, requeue_lst) def process_file(f_name): global Requeue_Article_lst count = -1 lst = load_batch(NewsBatchDir + f_name) if len(lst): reset_stats() try: if f_name[0] == '~': host = f_name[1:] else: host = f_name n = NNTP().init(host) print 'NNTP welcomes with \'' + n.getwelcome() + '\'' except error_temp, msg: print 'NNTP connect failed: ' + msg for item in lst: Requeue_Article_lst.append(item) return None for item in lst: count = count + 1 try: f = open(NewsSpoolDir + item[0],'r') except IOError: print 'opening of ' + NewsSpoolDir + item[0], print ' failed: ' + msg Stats['failed'] = Stats['failed'] + 1 continue try: Stats['offered'] = Stats['offered'] + 1 rtn = n.ihave(item[1],f) Stats['accepted'] = Stats['accepted'] + 1 except error_temp,msg: rtn_val = eval(msg[:3]) if rtn_val == ERR_XFERFAIL: print 'Transfer failed: Requeuing ' + item[1] Requeue_Article_lst.append(item) Stats['failed'] = Stats['failed'] + 1 if rtn_val == ERR_GOTIT: Stats['rejected'] = Stats['rejected'] + 1 except EOFError, msg: print 'Connection Closed!! requeueing items left' print 'Returned: ' + msg print 'Requeuing ' + `eval(len(lst) - count)` + ' items.' for items in lst[count:]: Requeue_Article_lst.append(items) return None n.quit() print_stats(host) return None # This is the main routine that runs everything def main(): global Stats global Requeue_Article_lst if not lock_dir(NewsBatchDir): print 'Could not lock \'' + NewsBatchDir + '\'.' print 'Try again later.' raise SystemExit do_list, redo_list = rtn_dirlist(NewsBatchDir) if redo_list != None and len(redo_list): for f_name in redo_list: process_file(f_name) if len(Requeue_Article_lst): write_requeue(f_name,Requeue_Article_lst) Requeue_Article_lst = [] if do_list != None and len(do_list): for f_name in do_list: process_file(f_name) if len(Requeue_Article_lst): write_requeue('~'+f_name,Requeue_Article_lst) Requeue_Article_lst = [] r = unlock_dir(NewsBatchDir) return None main() -- Lance Ellinghouse lance@markv.com 1231 bit key fingerprint = 56 DA 31 0C 17 51 36 6A 4E D4 E0 11 D9 B8 06 0A 1024 bit key fingerprint = 66 2C 75 F2 E9 1C 32 84 3A E3 B0 5E 48 01 4C 37 You can recieve my Public Key by `finger lance@mark.com` Replied: Sun, 01 Aug 1993 14:47:49 +0200 Replied: "Gerry Stringer <gerry@camscan.co.uk> python-list@cwi.nl" Received: from eros.uknet.ac.uk by charon.cwi.nl with SMTP id AA25159 (5.65b/3.8/CWI-Amsterdam); Sun, 1 Aug 1993 02:47:18 +0200 Received: from camscan.co.uk by eros.uknet.ac.uk with UUCP id <g.14448-0@eros.uknet.ac.uk>; Sun, 1 Aug 1993 01:46:59 +0100 Received: from electra.camscan.co.uk by star.camscan.co.uk; Sat, 31 Jul 93 13:23:27 BST From: Gerry Stringer <gerry@camscan.co.uk> Date: Sat, 31 Jul 93 13:23:31 BST Message-Id: <3070.9307311223@electra.camscan.co.uk> To: python-list@cwi.nl Subject: Re: revised import.c >I can see why you'd want this in certain cases, but when I designed >this code I made a conscious decision to require that the .py should >file be there for the .pyc file to be valid -- unlike Emacs .elc >files, .pyc files can be considered as pure caches and are managed >completely automatic. Perhaps Lance's version can be made into a >compile-time or run-time option? My vote goes for some runtime control in fact, as I've mentioned before, I'd actually like to be able to 'compile' Python code and run from memory. Just a thought. gerry (gerry@camscan.co.uk) Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA05793 (5.65b/3.8/CWI-Amsterdam); Sun, 1 Aug 1993 14:47:50 +0200 Received: by voorn.cwi.nl with SMTP id AA25592 (5.65b/3.8/CWI-Amsterdam); Sun, 1 Aug 1993 14:47:50 +0200 Message-Id: <9308011247.AA25592=guido@voorn.cwi.nl> To: Gerry Stringer <gerry@camscan.co.uk> Cc: python-list@cwi.nl Subject: Re: revised import.c In-Reply-To: Your message of "Sat, 31 Jul 1993 13:23:31 MDT." <3070.9307311223@electra.camscan.co.uk> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Sun, 01 Aug 1993 14:47:49 +0200 Sender: Guido.van.Rossum@cwi.nl > My vote goes for some runtime control in fact, as I've mentioned > before, I'd actually like to be able to 'compile' Python code and run > from memory. Note that you can do this with the new compile() built-in function which turns a string into a code object; exec() and eval() will accept code objects and run them. (This was done so I could implement the "freeze" script.) --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from ELVIS.TAMU.EDU by charon.cwi.nl with SMTP id AA18378 (5.65b/3.8/CWI-Amsterdam); Mon, 2 Aug 1993 19:00:14 +0200 Received: by elvis.tamu.edu (920330.SGI/920502.SGI.AUTO) for python-list@cwi.nl id AA29763; Mon, 2 Aug 93 11:58:09 -0500 Date: Mon, 2 Aug 93 11:58:09 -0500 From: allan@elvis.tamu.edu (Allan Bailey) Message-Id: <9308021658.AA29763@elvis.tamu.edu> To: python-list@cwi.nl Subject: MD5 problem in 0.9.9 I'm trying to compile the md5 stuff into python. I had to modify the md5 code from rsa.com to agree with the python code, but it seems to compile. When I run the demo though I get the following ---begin: [~/python/python/demo/md5test]$ ./md5driver.py -x MD5 test suite results: XXX lineno: 62, opcode: 212 Stack backtrace (innermost last): File "./md5driver.py", line 127 main() File "./md5driver.py", line 123 MDTestSuite() File "./md5driver.py", line 97 MDString('') File "./md5driver.py", line 62 MDPrint(md5(str).digest()) SystemError: eval_code: unknown opcode ---end: Any help would be appreciated. -- Allan Bailey, UNIX programmer, CSC | "Freedom is not free." Infinite Diversity in Infinite Combinations | or: allan.bailey@tamu.edu Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA20258 (5.65b/3.8/CWI-Amsterdam); Mon, 2 Aug 1993 19:57:57 +0200 To: python-list@cwi.nl Subject: XmNlabelString errors.... X-Organization: Mark V Systems Ltd. X-Address: 16400 Ventura Blvd Suite 303, Encino, Ca, 91436, USA X-Phone: +1 818 995 7671 (work), +1 818 995 4267 (fax) Date: Mon, 2 Aug 93 10:57:43 PDT From: lance@markv.com Sender: lance@markv.com Message-Id: <9308021057.aa21740@hermix.markv.com> Source-Info: From (or Sender) name not authenticated. I compiled the X11 support into Python 0.9.9 with no problems at all on SCO ODT 2.0 (just did not put in the EditRes module info). When I run a number of the sample/test programs, I get X errors stating that XmNlabelString should be a compound label. I cannot see where that is being set up in the code.. Anyone else see this? Anything I can do? -- Lance Ellinghouse lance@markv.com 1231 bit key fingerprint = 56 DA 31 0C 17 51 36 6A 4E D4 E0 11 D9 B8 06 0A 1024 bit key fingerprint = 66 2C 75 F2 E9 1C 32 84 3A E3 B0 5E 48 01 4C 37 You can recieve my Public Key by `finger lance@mark.com` Received: from ELVIS.TAMU.EDU by charon.cwi.nl with SMTP id AA05610 (5.65b/3.8/CWI-Amsterdam); Tue, 3 Aug 1993 01:06:10 +0200 Received: by elvis.tamu.edu (920330.SGI/920502.SGI.AUTO) for python-list@cwi.nl id AA04977; Mon, 2 Aug 93 18:05:57 -0500 Date: Mon, 2 Aug 93 18:05:57 -0500 From: allan@elvis.tamu.edu (Allan Bailey) Message-Id: <9308022305.AA04977@elvis.tamu.edu> To: python-list@cwi.nl Subject: md5.c: how to compile it in correctly? I've gotten the md5.c files from rsa.com, and i've gotten the ones from the pgp 2.3a distribution. The both don't work. Has anyone else gotten these to compile and work? I get segmentation faults because of bad pointer or something. ideas, hints welcome.... -- Allan Bailey, UNIX programmer, CSC | "Freedom is not free." Infinite Diversity in Infinite Combinations | or: allan.bailey@tamu.edu Received: from ELVIS.TAMU.EDU by charon.cwi.nl with SMTP id AA12587 (5.65b/3.8/CWI-Amsterdam); Tue, 3 Aug 1993 01:36:01 +0200 Received: by elvis.tamu.edu (920330.SGI/920502.SGI.AUTO) for python-list@cwi.nl id AA05522; Mon, 2 Aug 93 18:35:58 -0500 Date: Mon, 2 Aug 93 18:35:58 -0500 From: allan@elvis.tamu.edu (Allan Bailey) Message-Id: <9308022335.AA05522@elvis.tamu.edu> To: python-list@cwi.nl Subject: Re: md5.c: how to compile it in correctly? (never mind...) > >I've gotten the md5.c files from rsa.com, and i've gotten the >ones from the pgp 2.3a distribution. The both don't work. > >Has anyone else gotten these to compile and work? > >I get segmentation faults because of bad pointer or something. > >ideas, hints welcome.... > a few minutes after i sent this i took another look at the md5 code from rsa, and the md5module.c and realized that the &mdContext should be the 2nd arg and mdContext.digest should be the 1st. works spiffy now. sorry to bother y'all, but i'm just a beginner with this. -- Allan Bailey, UNIX programmer, CSC | "Freedom is not free." Infinite Diversity in Infinite Combinations | or: allan.bailey@tamu.edu Received: from ELVIS.TAMU.EDU by charon.cwi.nl with SMTP id AA19262 (5.65b/3.8/CWI-Amsterdam); Tue, 3 Aug 1993 02:32:06 +0200 Received: by elvis.tamu.edu (920330.SGI/920502.SGI.AUTO) for python-list@cwi.nl id AA06014; Mon, 2 Aug 93 19:11:46 -0500 Date: Mon, 2 Aug 93 19:11:46 -0500 From: allan@elvis.tamu.edu (Allan Bailey) Message-Id: <9308030011.AA06014@elvis.tamu.edu> To: python-list@cwi.nl Subject: python and linux Just a success note for Guido and the list: python 0.9.9, stdwin, readline, gmp, and md5 all go up on linux 0.99 pl11 with out much problems. If anyone is having problems trying to get python on their linux box compiled let me know and I'll help. -- Allan Bailey, UNIX programmer, CSC | "Freedom is not free." Infinite Diversity in Infinite Combinations | or: allan.bailey@tamu.edu Received: from ent-img.ent-img.com by charon.cwi.nl with SMTP id AA09169 (5.65b/3.8/CWI-Amsterdam); Tue, 3 Aug 1993 01:22:14 +0200 Received: from overlord.ent-img.com by gatekeeper.ent-img.com with smtp (Smail3.1.26.7 #4) id m0oN9Ch-0006qRC; Mon, 2 Aug 93 16:22 PDT Received: by overlord.ent-img.com (920330.SGI/920502.SGI) for @gatekeeper.ent-img.com:python-list@cwi.nl id AA06488; Mon, 2 Aug 93 16:22:06 -0700 From: kevin@overlord.ent-img.com (Kevin Gage) Message-Id: <9308022322.AA06488@overlord.ent-img.com> Subject: SGI compile To: python-list@cwi.nl Date: Mon, 2 Aug 1993 16:22:06 -0800 (PDT) X-Mailer: ELM [version 2.4 PL21] Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-Length: 348 I'm on a Indigo R3k and trying the basic compile. I've uncommented SYSVDEF=-DSYSV ,but I'm still getting an error: socketmodule.c:79: sys/socket.h: No such file or directory socketmodule.c:81: sys/un.h: No such file or directory *** Error code 1 Stop. Any help would be appreciated. Kevin D. Gage CST Entertainment Imaging Inc. Los Angeles Received: from helios.ath.epa.gov by charon.cwi.nl with SMTP id AA12615 (5.65b/3.8/CWI-Amsterdam); Tue, 3 Aug 1993 21:12:06 +0200 Received: by helios.ath.epa.gov (5.65c+/1.34) id AA09155; Tue, 3 Aug 1993 15:12:02 -0400 Date: Tue, 3 Aug 1993 15:12:02 -0400 From: Kevin Weinrich <kbw@helios.ath.epa.gov> Message-Id: <199308031912.AA09155@helios.ath.epa.gov> To: python-list@cwi.nl Subject: How to compile STDWIN on MS-DOS? I tried to ask Guido van Rossum this question, but his vacation-mail program says he'll be gone for the next 7 weeks. It said I should ask this group in his absence. Does anyone know how to compile STDWIN for MS-DOS? The README file said that it could be done, but not how. All the makefiles seem set up for UNIX. Alternatively, FTP sites where DOS executables are archived would help me out. Please e-mail any responses to me. I'm not subscribed to this group. --- Kevin Weinrich Atlantic Research Corp. (till August 1) kbw@helios.ath.epa.gov Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA12488 (5.65b/3.8/CWI-Amsterdam); Wed, 4 Aug 1993 04:11:55 +0200 To: python-list@cwi.nl Subject: md5 source X-Organization: Mark V Systems Ltd. X-Address: 16400 Ventura Blvd Suite 303, Encino, Ca, 91436, USA X-Phone: +1 818 995 7671 (work), +1 818 995 4267 (fax) Date: Tue, 3 Aug 93 19:11:08 PDT From: lance@markv.com Sender: lance@markv.com Message-Id: <9308031911.aa02342@hermix.markv.com> Source-Info: From (or Sender) name not authenticated. Can someone send me the md5 source that WORKS with python 0.9.9's md5module.c??? the MD5_CNTX structure does not seem to be compatible... Please don't tell me where to get it, just send me the files PLEASE! (unless it is on a FTP site, and the code WILL work) Thank you!!! -- Lance Ellinghouse lance@markv.com 1231 bit key fingerprint = 56 DA 31 0C 17 51 36 6A 4E D4 E0 11 D9 B8 06 0A 1024 bit key fingerprint = 66 2C 75 F2 E9 1C 32 84 3A E3 B0 5E 48 01 4C 37 You can recieve my Public Key by `finger lance@mark.com` Received: from ansjovis.cwi.nl by charon.cwi.nl with SMTP id AA24291 (5.65b/3.8/CWI-Amsterdam); Wed, 4 Aug 1993 09:41:28 +0200 Received: by ansjovis.cwi.nl with SMTP id AA10816 (5.65b/3.8/CWI-Amsterdam); Wed, 4 Aug 1993 09:41:28 +0200 Message-Id: <9308040741.AA10816=sjoerd@ansjovis.cwi.nl> To: lance@markv.com Cc: python-list@cwi.nl Subject: Re: md5 source In-Reply-To: Your message of Tue, 03 Aug 1993 19:11:08 -0700. <9308031911.aa02342@hermix.markv.com> Date: Wed, 04 Aug 1993 09:41:27 +0200 From: Sjoerd Mullender <Sjoerd.Mullender@cwi.nl> On Tue, Aug 3 1993 lance@markv.com wrote: > Can someone send me the md5 source that WORKS with python 0.9.9's > md5module.c??? the MD5_CNTX structure does not seem to be > compatible... > > Please don't tell me where to get it, just send me the files PLEASE! > (unless it is on a FTP site, and the code WILL work) I have put a copy of our version of md5 on ftp.cwi.nl in directory /pub/md5. It is the version we use at CWI, so I think it will work with python. Sjoerd Mullender CWI, dept. CST, Kruislaan 413, 1098 SJ Amsterdam, Netherlands email: Sjoerd.Mullender@cwi.nl fax: +31 20 592 4199 phone: +31 20 592 4127 telex: 12571 mactr nl Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA29736 (5.65b/3.8/CWI-Amsterdam); Wed, 4 Aug 1993 17:49:31 +0200 To: Sjoerd.Mullender@cwi.nl Cc: python-list@cwi.nl In-Reply-To: <9308040741.AA10816=sjoerd@ansjovis.cwi.nl> (message from Sjoerd Mullender on Wed, 04 Aug 1993 09:41:27 +0200) Subject: Re: md5 source X-Organization: Mark V Systems Ltd. X-Address: 16400 Ventura Blvd Suite 303, Encino, Ca, 91436, USA X-Phone: +1 818 995 7671 (work), +1 818 995 4267 (fax) Date: Wed, 4 Aug 93 8:48:35 PDT From: lance@markv.com Sender: lance@markv.com Message-Id: <9308040848.aa14987@hermix.markv.com> Source-Info: From (or Sender) name not authenticated. > On Tue, Aug 3 1993 lance@markv.com wrote: > > > Can someone send me the md5 source that WORKS with python 0.9.9's > > md5module.c??? the MD5_CNTX structure does not seem to be > > compatible... > > > > Please don't tell me where to get it, just send me the files PLEASE! > > (unless it is on a FTP site, and the code WILL work) > > I have put a copy of our version of md5 on ftp.cwi.nl in directory > /pub/md5. It is the version we use at CWI, so I think it will work > with python. > Great!!!! Thank you very much!! -- Lance Ellinghouse lance@markv.com 1231 bit key fingerprint = 56 DA 31 0C 17 51 36 6A 4E D4 E0 11 D9 B8 06 0A 1024 bit key fingerprint = 66 2C 75 F2 E9 1C 32 84 3A E3 B0 5E 48 01 4C 37 You can recieve my Public Key by `finger lance@mark.com` Received: from alpha.Xerox.COM by charon.cwi.nl with SMTP id AA13335 (5.65b/3.9/CWI-Amsterdam); Fri, 6 Aug 1993 20:05:16 +0200 Received: from eros.EuroPARC.Xerox.COM ([13.1.252.143]) by alpha.xerox.com with SMTP id <11905>; Fri, 6 Aug 1993 11:04:54 PDT Received: by eros.EuroPARC.Xerox.COM with SMTP (5.65c/IDA-1.2.9) id AA00161; Fri, 6 Aug 1993 19:04:27 +0100 Message-Id: <199308061804.AA00161@eros.EuroPARC.Xerox.COM> To: python-list@cwi.nl Subject: bug in sorting? Date: Fri, 6 Aug 1993 11:04:24 PDT From: Fraser@europarc.xerox.com The following little program causes my python to core dump with a bus error. Could others try it and see if it does the same? As far as I can see, the objects passed to the compare function are corrupted in some way and the first operation on either one causes a crash. It doesn't do it with 0.9.8. I've had a brief browse with my debugger but without much luck. Ta, Quentin -------------- #! /usr/local/bin/python def compare(l1,l2): if l1 < l2: return -1 if l1 > l2: return 1 return 0 names = ['joe', 'fred', 'peter'] names.sort(compare) for i in names: print i ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Quentin Stafford-Fraser Tel: +44 223 341521 Rank Xerox EuroPARC, Fax: +44 223 341510 61 Regent Street, Home: +44 223 324451 Cambridge, CB2 1AB United Kingdom Fraser@europarc.xerox.com Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA15904 (5.65b/3.9/CWI-Amsterdam); Fri, 6 Aug 1993 21:41:14 +0200 Received: from eng1.sequent.com by gateway.sequent.com (5.61/1.34) id AA16149; Fri, 6 Aug 93 12:37:56 -0700 Received: by eng1.sequent.com (5.65/crg/11) id AA19081; Fri, 6 Aug 93 12:39:18 -0700 Message-Id: <9308061939.AA19081@eng1.sequent.com> To: Fraser@europarc.xerox.com Cc: python-list@cwi.nl Subject: Re: bug in sorting? Priority: Normal Precedence: first-class Organization: Sequent Computer Systems, Inc. Service Technology - MailStop: WIL2-610 15450 S.W. Koll Parkway Beaverton, OR 97006-6063 X-Phone: (503) 578-4404 X-Fax: (503) 578-4540 X-Uucp: ...!uunet!sequent!jaap X-Internet: jaap@sequent.com X-Face: C4Cnai$>Eja5I6Vq?(gdN#SXX#`-XgAnmUn&e54sx7@1>q@vkrd_XnH![P>w.:7IJJ;{Bts WJd)u&G!V}0OR?2o5cUgIY}.T{g]PMC=*~]3n_t)S-ZkC(WG}3:#hcA6Oazx:}yc&k,hsF7D},7x>l nyfRjO7$@]fHBN>aC9-M3pKfbYHiy!PWD{_bx~fo})b4tU.;Ao%x[upCI, In-Reply-To: Fraser@europarc.xerox.com's message of Fri, 06 Aug 1993 11:04:24 -0700. <199308061804.AA00161@eros.EuroPARC.Xerox.COM> Date: Fri, 06 Aug 1993 12:39:18 -0700 From: Jaap Vermeulen <jaap@sequent.com> | The following little program causes my python to core dump with a bus | error. Could others try it and see if it does the same? As far as I | can see, the objects passed to the compare function are corrupted in | some way and the first operation on either one causes a crash. It | doesn't do it with 0.9.8. I've had a brief browse with my debugger but | without much luck. After staring at it a little, I figured it out. It should be passing (object *) to mkvalue(), not (object **) in listobject.c:cmp(). Here's the patch: *** listobject.c.Save Thu Jul 29 01:25:08 1993 --- listobject.c Fri Aug 6 12:33:24 1993 *************** *** 520,526 return cmpobject(* (object **) v, * (object **) w); /* Call the user-supplied comparison function */ ! t = mkvalue("OO", v, w); if (t == NULL) return 0; res = call_object(cmpfunc, t); --- 520,526 ----- return cmpobject(* (object **) v, * (object **) w); /* Call the user-supplied comparison function */ ! t = mkvalue("OO", * (object **) v, * (object **) w); if (t == NULL) return 0; res = call_object(cmpfunc, t); Have fun, -Jaap- Received: from nic.eunet.no by charon.cwi.nl with SMTP id AA18842 (5.65b/3.9/CWI-Amsterdam); Tue, 10 Aug 1993 13:46:01 +0200 Received: from dms.corena.no by Norway.EU.net with UUCP id AA20475 (5.65c8/IDA-1.4.4/EUnet/NO for python-list@cwi.nl); Tue, 10 Aug 1993 13:45:54 +0200 Received: from canis by dms.corena.no (AIX 3.2/UCB 5.64/4.03) id AA44304; Tue, 10 Aug 1993 13:42:54 +0200 Received: from tropical by nis.corena.no (AIX 3.2/UCB 5.64/4.03) id AA27701; Tue, 10 Aug 1993 13:42:31 +0200 Received: by tropical (AIX 3.2/UCB 5.64/4.03) id AA49895; Tue, 10 Aug 1993 13:41:06 +0200 Date: Tue, 10 Aug 1993 13:41:06 +0200 From: lars@dms.corena.no (Lars Tafjord) Message-Id: <9308101141.AA49895@tropical> To: python-list@cwi.nl Subject: INCREF & DECREF Hi! I am still a newcomer to Python and have a few annoying core-dump problems. Could someone give some hints on _why_ and _how_ I should use INCREF, DECREF, XDECREF and any other related functions/macros? --------------------------------------------------------------- Lars Tafjord Corena A/S, N-1370 ASKER NORWAY lars@corena.no +47 66 79 45 00 --------------------------------------------------------------- Received: from ansjovis.cwi.nl by charon.cwi.nl with SMTP id AA20285 (5.65b/3.9/CWI-Amsterdam); Tue, 10 Aug 1993 14:53:42 +0200 Received: by ansjovis.cwi.nl with SMTP id AA21444 (5.65b/3.8/CWI-Amsterdam); Tue, 10 Aug 1993 14:53:41 +0200 Message-Id: <9308101253.AA21444=sjoerd@ansjovis.cwi.nl> To: lars@dms.corena.no (Lars Tafjord) Cc: python-list@cwi.nl Subject: Re: INCREF & DECREF In-Reply-To: Your message of Tue, 10 Aug 1993 13:41:06 +0200. <9308101141.AA49895@tropical> Date: Tue, 10 Aug 1993 14:53:41 +0200 From: Sjoerd Mullender <Sjoerd.Mullender@cwi.nl> Guido is on vacation, so I'll try to answer your question. If I am wrong somebody will no doubt correct me. On Tue, Aug 10 1993 Lars Tafjord wrote: > I am still a newcomer to Python and have a few annoying core-dump > problems. Could someone give some hints on _why_ and _how_ I should > use INCREF, DECREF, XDECREF and any other related functions/macros? Use XINCREF or XDECREF instead of INCREF/DECREF when the argument may be NULL. The basic idea is, if you create an extra reference to an object, you must INCREF it, if you throw away a reference to an object, you must DECREF it. Functions such as newstringobject, newsizedstringobject, newintobject, etc. create a reference to an object. If you want to throw away the object thus created, you must use DECREF. If you put an object into a tuple, list, or dictionary, the idea is that you usually don't want to keep a reference of your own around, so Python does not INCREF the elements. It does DECREF the old value. This means that if you put something into such an object using the functions Python provides for this, you must INCREF the object if you want to keep a separate reference to the object around. Also, if you replace an element, you should INCREF the old element first if you want to keep it. If you didn't INCREF it before you replaced it, you are not allowed to look at it anymore, since it may have been freed. Returning an object to Python (i.e., when your module function returns) creates a reference to an object, but it does not change the reference count. When your module does not keep another reference to the object, you should not INCREF or DECREF it. When you do keep a reference around, you should INCREF the object. Also, when you return a global object such as None, you should INCREF it. If you want to return a tuple, you should consider using mkvalue. Mkvalue creates a new tuple with a reference count of 1 which you can return. If any of the elements you put into the tuple are objects, they are INCREFfed by mkvalue. If you don't want to keep references to those elements around, you should DECREF them after having called mkvalue. Usually you don't have to worry about arguments. They are INCREFfed before your function is called and DECREFfed after your function returns. When you keep a reference to an argument, you should INCREF it and DECREF when you throw it away. Also, when you return an argument, you should INCREF it, because returning the argument creates an extra reference to it. If you use getargs() to parse the arguments, you can get a reference to an object (by using "O" in the format string). This object was not INCREFfed, so you should not DECREF it. If you want to keep the object, you must INCREF it yourself. If you create your own type of objects, you should use NEWOBJ to create the object. This sets the reference count to 1. If you want to throw away the object, you should use DECREF. When the reference count reaches 0, the dealloc function is called. In it, you should DECREF all object to which you keep references in your object, but you should not use DECREF on your object. You should use DEL instead. Sjoerd Mullender CWI, dept. CST, Kruislaan 413, 1098 SJ Amsterdam, Netherlands email: Sjoerd.Mullender@cwi.nl fax: +31 20 592 4199 phone: +31 20 592 4127 telex: 12571 mactr nl Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA09952 (5.65b/3.9/CWI-Amsterdam); Fri, 13 Aug 1993 17:51:06 +0200 From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: python-list@cwi.nl Subject: updated nntpxmit.py file... Date: Fri, 13 Aug 93 8:50:33 PDT Message-Id: <9308130850.aa26272@hermix.markv.com> I have fixed a number of crashes and dumps that I was not expecting in the nntpxmit.py file I posted a while ago.. It has been up and running for almost 2 weeks straight now! (that's about 2 weeks more than the original nntpxmit!) Lance Ellinghouse lance@markv.com ===== #! /usr/local/bin/python # This file reads the batch files created by NNTP and # sends the messages to the remote site. # The usage for this program is: # # nntpxmit Batch_dir News_dir import sys import strop import posix import socket from nntplib import NNTP, error_temp, error_reply, error_perm False = 0 True = 1 ##### # Global locations to use ##### NewsSpoolDir = '' NewsBatchDir = '' if len(sys.argv) != 3: print 'Usage: ' + sys.argv[0] + ' NNTP_Batch_Dir NEWS_Directory' raise SystemExit NewsSpoolDir = sys.argv[2] + '/' NewsBatchDir = sys.argv[1] + '/' NewsBatchHost= '' ##### # Codes returned from NNTP Server ##### OK_NOPOST = 201 OK_CANPOST = 200 OK_XFERD = 235 CONT_XFER = 335 ERR_GOTIT = 435 ERR_XFERRJCT = 437 ERR_XFERFAIL = 436 ##### # Globals ##### # Transfer Stats Stats = { 'offered':0, 'accepted':0, 'rejected':0, 'failed':0 } Debug = False Report_Stats = True ReQueue_fails = True Debug_Stream = None Requeue_Article_lst = [] ##### # Support Functions ##### def reset_stats(): global Stats Stats['offered'] = 0 Stats['accepted'] = 0 Stats['rejected'] = 0 Stats['failed'] = 0 return None def print_stats(host): global Stats print '' print 'Statistics for \'' + host + '\'' print '='*30 print 'Offered : ' + `Stats['offered']` print 'Accepted : ' + `Stats['accepted']` print 'Rejected : ' + `Stats['rejected']` print 'Failed : ' + `Stats['failed']` print '' return None def write_requeue(file_name, lst): try: fp = open(NewsBatchDir + file_name,'a+') except IOError, msg: print 'write_requeue(' + NewsBatchDir + file_name + ') failed: ' + msg return None if len(lst) == 0: fp.close() return None for item in lst: try: fp.write(item[0] + ' ' + item[1] + '\n') except IOError, msg: print 'write_requeue(' + NewsBatchDir + file_name + ') failed: ' + msg return None return None # This routine takes a file name and loads all the lines in the file # into a list. This list contains 2 parts, ('filename','message id') # This information is taked from a batch file def load_batch(file_name): try: fp = open(file_name,'r') except: return None list = [] list = fp.readlines() for ndx in range(len(list)): list_el = strop.strip(list[ndx]) l = len(list_el) j = 0 while j < l and list_el[j] != ' ': j = j + 1 fn = list_el[0:j] msgid = list_el[j:] list[ndx] = (strop.strip(fn),strop.strip(msgid)) try: t = posix.unlink(file_name) except: pass return list # this will lock a directory def lock_dir(dir_to_lock): t_dir = posix.getcwd() r = posix.chdir(dir_to_lock) try: r = open('.LCK'+`posix.getpid()`,'w') except: r = posix.chdir(t_dir) return False r.close() try: r = posix.link('.LCK'+`posix.getpid()`,'.LCKdir') except: r = posix.chdir(t_dir) return False r = posix.chdir(t_dir) return True # This will unlock the directory def unlock_dir(dir_to_unlock): t_dir = posix.getcwd() r = posix.chdir(dir_to_unlock) try: r = posix.unlink('.LCKdir') r = posix.unlink('.LCK'+`posix.getpid()`) except: return False r = posix.chdir(t_dir) return True # This function returns 2 lists.. # 1: A list of all files in the directory that are NOT requeue files (! '~xxx') # 2: A list of all files in the directory that are requeue files (~xxx) # This function NEVER returns files that start as '.LCK' as these # are lock files and Never need to be touched and it never returns # files that start with '.' as these are hidden def rtn_dirlist(dir_to_list): requeue_lst = [] rtn_lst = [] try: lst = posix.listdir(dir_to_list) except: return (None, None) for i in range(len(lst)): name = lst[i] if name[0] == '.': continue if name[0] == '~': r = requeue_lst.append(name) continue rtn_lst.append(name) return (rtn_lst, requeue_lst) def process_file(f_name): global Requeue_Article_lst count = -1 lst = load_batch(NewsBatchDir + f_name) if len(lst): reset_stats() try: if f_name[0] == '~': host = f_name[1:] else: host = f_name print 'Connecting to ' + host n = NNTP().init(host) print 'NNTP welcomes with \'' + n.getwelcome() + '\'' except (EOFError,IOError,error_temp,error_perm,socket.error), msg: print 'NNTP connect failed: ' + `msg` for item in lst: Requeue_Article_lst.append(item) return None for item in lst: count = count + 1 try: f = open(NewsSpoolDir + item[0],'r') except IOError, msg: print 'opening of ' + NewsSpoolDir + item[0], print ' failed: ' + `msg` Stats['failed'] = Stats['failed'] + 1 continue try: Stats['offered'] = Stats['offered'] + 1 rtn = n.ihave(item[1],f) Stats['accepted'] = Stats['accepted'] + 1 except error_temp,msg: rtn_val = eval(msg[:3]) if rtn_val == ERR_XFERFAIL: print 'Transfer failed: Requeuing ' + item[1] Requeue_Article_lst.append(item) Stats['failed'] = Stats['failed'] + 1 if rtn_val == ERR_GOTIT: Stats['rejected'] = Stats['rejected'] + 1 except EOFError, msg: print 'Connection Closed!! requeueing items left' print 'Returned: ' + `msg` num_left = len(lst) - count print 'Requeuing ' + `num_left` + ' items.' for items in lst[count:]: Requeue_Article_lst.append(items) return None n.quit() print_stats(host) return None # This is the main routine that runs everything def main(): global Stats global Requeue_Article_lst if not lock_dir(NewsBatchDir): print 'Could not lock \'' + NewsBatchDir + '\'.' print 'Try again later.' raise SystemExit do_list, redo_list = rtn_dirlist(NewsBatchDir) if redo_list != None and len(redo_list): for f_name in redo_list: process_file(f_name) if len(Requeue_Article_lst): write_requeue(f_name,Requeue_Article_lst) Requeue_Article_lst = [] if do_list != None and len(do_list): for f_name in do_list: process_file(f_name) if len(Requeue_Article_lst): write_requeue('~'+f_name,Requeue_Article_lst) Requeue_Article_lst = [] r = unlock_dir(NewsBatchDir) return None main() Received: from hopscotch.ksr.com by charon.cwi.nl with SMTP id AA06775 (5.65b/3.9/CWI-Amsterdam); Tue, 17 Aug 1993 05:00:58 +0200 Received: from ksr.com (frankenstein.ksr.com) by hopscotch.ksr.com with SMTP id AA17740; Mon, 16 Aug 1993 22:59:41 -0400 Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA25341; Mon, 16 Aug 93 22:59:36 EDT Received: by kaos.ksr.com (4.1/KSR-2.0) id AA26538; Mon, 16 Aug 93 22:59:33 EDT Message-Id: <9308170259.AA26538@kaos.ksr.com> To: python-list@cwi.nl Subject: Date objects Date: Mon, 16 Aug 93 22:59:32 -0400 From: Tim Peters <tim@ksr.com> Attached is module Dates.py, which supplies a handy Date class that supports date arithmetic (e.g., Dates.today() + 40*7 returns the date 40 weeks from now, Dates.Date(12,25,1993)-Dates.today() is the number of days until Christmas, etc). It uses features new in Python 0.9.9, so you'll need to bring up the new release first; in return, I've extended this to allow use of new 0.9.9 capabilites (e.g., Date objects can be used as dictionary keys under 0.9.9). I have 3 reasons for sending it out: 1) I've found various versions of this to be useful, so maybe you will too. Python's actual coercion rules aren't documented in full, so maybe studying this will save you some poke-and-hope time too. 2) I'm wondering whether anyone sees a better way to worm around the coercion problems (date+date doesn't make sense, but date-date does and doesn't at all mean the same thing as date-int; etc). The sole advantage of the strange method used here is that it works. 3) I'm wondering whether other people have tried to implement new "numeric" types, and if so how that went for them. I'm particularly curious as to whether you found that automatic coercion was more of a help or a stumbling block. On the one hand, int+new_type has to go thru _some_ trickery else new_type.__add__ would get the arguments in the wrong order (as int*new_type already does ...); on the other, sometimes you really don't want to lose the info that the left (or right) argument was an int. That suggests: (a) no automatic coercion; and (b), the __add__ etc methods would be better as two methods, say __addl__ and __addr__, that distinguished between new-type-was-on-the-left and new-type- was-on-the-right. It also suggests that maybe date arithmetic is an abuse of the intended uses <grin>. curiously y'rs - tim Tim Peters tim@ksr.com not speaking for Kendall Square Research Corp # Class Date supplies date objects that support date arithmetic. # # Date(month,day,year) returns a Date object. An instance prints as, # e.g., 'Mon 16 Aug 1993'. # # Addition, subtraction, comparison operators, min, max, and sorting # all work as expected for date objects: int+date or date+int returns # the date `int' days from `date'; date+date raises an exception; # date-int returns the date `int' days before `date'; date2-date1 returns # an integer, the number of days from date1 to date2; int-date raises an # exception; date1 < date2 is true iff date1 occurs before date2 (& # similarly for other comparisons); min(date1,date2) is the earlier of # the two dates and max(date1,date2) the later; and date objects can be # used as dictionary keys. # # Date objects support one visible method, date.weekday(). This returns # the day of the week the date falls on, as a string. # # Date objects also have 4 (conceptually) read-only data attributes: # .month in 1..12 # .day in 1..31 # .year int or long int # .ord the ordinal of the date relative to an arbitrary staring point # # The Dates module also supplies function today(), which returns the # current date as a date object. # # Those entranced by calendar trivia will be disappointed, as no attempt # has been made to accommodate the Julian (etc) system. On the other # hand, at least this package knows that 2000 is a leap year but 2100 # isn't, and works fine for years with a hundred decimal digits <wink>. _MONTH_NAMES = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ] _DAY_NAMES = [ 'Friday', 'Saturday', 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday' ] _DAYS_IN_MONTH = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ] _DAYS_BEFORE_MONTH = [] dbm = 0 for dim in _DAYS_IN_MONTH: _DAYS_BEFORE_MONTH.append(dbm) dbm = dbm + dim del dbm, dim _INT_TYPES = type(1), type(1L) def _is_leap( year ): # 1 if leap year, else 0 if year % 4 != 0: return 0 if year % 400 == 0: return 1 return year % 100 != 0 def _days_in_year( year ): # number of days in year return 365 + _is_leap(year) def _days_before_year( year ): # number of days before year return year*365L + (year+3)/4 - (year+99)/100 + (year+399)/400 def _days_in_month( month, year ): # number of days in month of year if month == 2 and _is_leap(year): return 29 return _DAYS_IN_MONTH[month-1] def _days_before_month( month, year ): # number of days in year before month return _DAYS_BEFORE_MONTH[month-1] + (month > 2 and _is_leap(year)) def _date2num( date ): # compute ordinal of date.month,day,year return _days_before_year( date.year ) + \ _days_before_month( date.month, date.year ) + \ date.day _DI400Y = _days_before_year( 400 ) # number of days in 400 years def _num2date( n ): # return date with ordinal n if type(n) not in _INT_TYPES: raise TypeError, 'argument must be integer: ' + `type(n)` ans = Date(1,1,1) # arguments irrelevant; just getting a Date obj ans.ord = n n400 = (n-1)/_DI400Y # # of 400-year blocks preceding year, n = 400 * n400, n - _DI400Y * n400 more = n / 365 dby = _days_before_year( more ) if dby >= n: more = more - 1 dby = dby - _days_in_year( more ) year, n = year + more, int(n - dby) try: year = int(year) # chop to int, if it fits except ValueError: pass month = min( n/29 + 1, 12 ) dbm = _days_before_month( month, year ) if dbm >= n: month = month - 1 dbm = dbm - _days_in_month( month, year ) ans.month, ans.day, ans.year = month, n-dbm, year return ans def _num2day( n ): # return weekday name of day with ordinal n return _DAY_NAMES[ int(n % 7) ] class Date: def __init__( self, month, day, year ): if not 1 <= month <= 12: raise ValueError, 'month must be in 1..12: ' + `month` dim = _days_in_month( month, year ) if not 1 <= day <= dim: raise ValueError, 'day must be in 1..' + `dim` + ': ' + `day` self.month, self.day, self.year = month, day, year self.ord = _date2num( self ) def __cmp__( self, other ): return cmp( self.ord, other.ord ) # define a hash function so dates can be used as dictionary keys def __hash__( self ): return hash( self.ord ) # print as, e.g., Mon 16 Aug 1993 def __repr__( self ): return '%.3s %2d %.3s ' % ( self.weekday(), self.day, _MONTH_NAMES[self.month-1] ) + `self.year` # automatic coercion is a pain for date arithmetic, since e.g. # date-date and date-int mean different things. So, in order to # sneak integers past Python's coercion rules without losing the info # that they're really integers (& not dates!), integers are disguised # as instances of the derived class _DisguisedInt. That this works # relies on undocumented behavior of Python's coercion rules. def __coerce__( self, other ): if type(other) in _INT_TYPES: return self, _DisguisedInt(other) # if another Date, fine if type(other) is type(self) and other.__class__ is Date: return self, other # Python coerces int+date, but not date+int; in the former case, # _DisguisedInt.__add__ handles it, so we only need to do # date+int here def __add__( self, n ): if type(n) not in _INT_TYPES: raise TypeError, 'can\'t add ' + `type(n)` + ' to date' return _num2date( self.ord + n ) # Python coerces all of int-date, date-int and date-date; the first # case winds up in _DisguisedInt.__sub__, leaving the latter two # for us def __sub__( self, other ): if other.__class__ is _DisguisedInt: # date-int return _num2date( self.ord - other.ord ) else: return self.ord - other.ord # date-date def weekday( self ): return _num2day( self.ord ) # see comments before Date.__add__ class _DisguisedInt( Date ): def __init__( self, n ): self.ord = n # handle int+date def __add__( self, other ): return other.__add__( self.ord ) # complain about int-date def __sub__( self, other ): raise TypeError, 'Can\'t subtract date from integer' def today(): import time local = time.localtime(time.time()) return Date( local[1], local[2], local[0] ) DateTestError = 'DateTestError' def test( firstyear, lastyear ): a = Date(9,30,1913) b = Date(9,30,1914) if `a` != 'Tue 30 Sep 1913': raise DateTestError, '__repr__ failure' if (not a < b) or a == b or a > b or b != b or \ a != 698982 or 698982 != a or \ (not a > 5) or (not 5 < a): raise DateTestError, '__cmp__ failure' if a+365 != b or 365+a != b: raise DateTestError, '__add__ failure' if b-a != 365 or b-365 != a: raise DateTestError, '__sub__ failure' try: x = 1 - a raise DateTestError, 'int-date should have failed' except TypeError: pass try: x = a + b raise DateTestError, 'date+date should have failed' except TypeError: pass if a.weekday() != 'Tuesday': raise DateTestError, 'weekday() failure' if max(a,b) is not b or min(a,b) is not a: raise DateTestError, 'min/max failure' d = {a-1:b, b:a+1} if d[b-366] != b or d[a+(b-a)] != Date(10,1,1913): raise DateTestError, 'dictionary failure' # verify date<->number conversions for first and last days for # all years in firstyear .. lastyear lord = _days_before_year( firstyear ) y = firstyear while y <= lastyear: ford = lord + 1 lord = ford + _days_in_year(y) - 1 fd, ld = Date(1,1,y), Date(12,31,y) if (fd.ord,ld.ord) != (ford,lord): raise DateTestError, ('date->num failed', y) fd, ld = _num2date(ford), _num2date(lord) if (1,1,y,12,31,y) != \ (fd.month,fd.day,fd.year,ld.month,ld.day,ld.year): raise DateTestError, ('num->date failed', y) y = y + 1 >>> END OF MSG Received: from schelvis.cwi.nl by charon.cwi.nl with SMTP id AA22278 (5.65b/3.9/CWI-Amsterdam); Tue, 17 Aug 1993 11:33:43 +0200 Received: by schelvis.cwi.nl with SMTP id AA02991 (5.65b/3.8/CWI-Amsterdam); Tue, 17 Aug 1993 11:33:41 +0200 Message-Id: <9308170933.AA02991=jack@schelvis.cwi.nl> To: Tim Peters <tim@ksr.com> Cc: python-list@cwi.nl Subject: Re: Date objects In-Reply-To: Message by Tim Peters <tim@ksr.com> , Mon, 16 Aug 93 22:59:32 -0400 , <9308170259.AA26538@kaos.ksr.com> Organisation: Multi-media group, CWI, Kruislaan 413, Amsterdam Phone: +31 20 5924098(work), +31 20 5924199 (fax), +31 20 6160335(home) X-Last-Band-Seen: Manic Street Preachers (Melkweg, 15-8), Windmills (Kroeg) X-Mini-Review: MSP: uneventful. Windmills: Great! Date: Tue, 17 Aug 1993 11:33:40 +0200 From: Jack Jansen <Jack.Jansen@cwi.nl> Wonderful! This means that an unbirthday program in python is now only a couple of lines: import Date import sys print 'Enter your day of birth as (day, month, year) - ' d, m, y = eval(sys.stdin.readline()) birth = Date.Date(m, d, y) today = Date.today() this_years_birthday = Date.Date(m, d, today.year) if this_years_birthday == today: print 'It is your', `today.year-y`+'th birthday today! Congratulations!' else: unbirthday = (today-birth)-(today.year-y) if this_years_birthday > today: unbirthday = unbirthday + 1 print 'Today is your', `int(unbirthday)`+'th unbirthday today! Congratulations!' -- Jack Jansen | If I can't dance I don't want to be part of Jack.Jansen@cwi.nl | your revolution -- Emma Goldman uunet!cwi.nl!jack G=Jack;S=Jansen;O=cwi;PRMD=surf;ADMD=400net;C=nl Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA21447 (5.65b/3.9/CWI-Amsterdam); Sat, 21 Aug 1993 01:54:38 +0200 From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: python-list@cwi.nl Subject: PYTHON FTP sites... Date: Fri, 20 Aug 93 16:53:59 PDT Message-Id: <9308201654.aa25072@hermix.markv.com> Are there any FTP sites for PYTHON code besides ftp.cwi.nl??? Lance Ellinghouse lance@markv.com Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA00792 (5.65b/3.10/CWI-Amsterdam); Wed, 25 Aug 1993 20:33:12 +0200 From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: python-list@cwi.nl Subject: rpc.py Date: Wed, 25 Aug 93 11:32:00 PDT Message-Id: <9308251132.aa15655@hermix.markv.com> I am working with the rpc.py module to create a set of server/client processes.. The problem I am having is that I wish to define a class that uses the Server and Client classes as: class MyServer(TCPServer, TCPClient): ...... I can use any method in TCPServer, but I cannot use any methods in TCPClient. It does not seem to see the TCPClient at all.. I DO NOT call the TCPClient.init() routine since I already call the TCPServer.init() call... Does this have something to do with it? Thank you! Lance Ellinghouse lance@markv.com Received: from ansjovis.cwi.nl by charon.cwi.nl with SMTP id AA06232 (5.65b/3.10/CWI-Amsterdam); Wed, 25 Aug 1993 23:53:32 +0200 Received: by ansjovis.cwi.nl with SMTP id AA15498 (5.65b/3.8/CWI-Amsterdam); Wed, 25 Aug 1993 23:53:31 +0200 Message-Id: <9308252153.AA15498=sjoerd@ansjovis.cwi.nl> To: Lance Ellinghouse <lance@markv.com> Cc: python-list@cwi.nl Subject: Re: rpc.py In-Reply-To: Your message of Wed, 25 Aug 1993 11:32:00 -0700. <9308251132.aa15655@hermix.markv.com> Date: Wed, 25 Aug 1993 23:53:30 +0200 From: Sjoerd Mullender <Sjoerd.Mullender@cwi.nl> On Wed, Aug 25 1993 Lance Ellinghouse wrote: > I am working with the rpc.py module to create a set of server/client > processes.. The problem I am having is that I wish to define a > class that uses the Server and Client classes as: > > class MyServer(TCPServer, TCPClient): > ...... > > I can use any method in TCPServer, but I cannot use any methods in > TCPClient. It does not seem to see the TCPClient at all.. > I DO NOT call the TCPClient.init() routine since I already call > the TCPServer.init() call... Does this have something to do with it? It seems to me that you are trying to live dangerously. I don't know the rpc module, but I had a quick look, and it seems that both classes use the same names for instance variables. This means that you really have only one set of instance variables instead of one for both the server and the client. An alternative would be to not inherit from the two classes but to create instance variables in your class that are instances of the two classes you mention: class MyServer: def init(self,...): self.server = TCPServer().init(...) self.client = TCPClient().init(...) Ordinarily, if you inherit from two super classes, you should call the init() methods of both super classes. Sjoerd Mullender CWI, dept. CST, Kruislaan 413, 1098 SJ Amsterdam, Netherlands email: Sjoerd.Mullender@cwi.nl fax: +31 20 592 4199 phone: +31 20 592 4127 telex: 12571 mactr nl Received: from hopscotch.ksr.com by charon.cwi.nl with SMTP id AA07704 (5.65b/3.10/CWI-Amsterdam); Thu, 26 Aug 1993 11:16:27 +0200 Received: from ksr.com (frankenstein.ksr.com) by hopscotch.ksr.com with SMTP id AA07627; Thu, 26 Aug 1993 05:15:29 -0400 Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA27612; Thu, 26 Aug 93 05:15:14 EDT Received: by kaos.ksr.com (4.1/KSR-2.0) id AA03341; Thu, 26 Aug 93 05:14:42 EDT Message-Id: <9308260914.AA03341@kaos.ksr.com> To: python-list@cwi.nl, allen@ksr.com Subject: Rats Date: Thu, 26 Aug 93 05:14:42 -0400 From: Tim Peters <tim@ksr.com> Attached is a drop-in replacement for the rational-arithmetic class distributed as python/demo/classes/Rat.py. In comparison to that, this version: - plugs some holes - adds support for 0.9.9 features (e.g., a rat can be used as a dictionary key) - suffers spurious overflow less often for short-rat operations (and never for * and / and comparisons) - runs much faster for long-rat operations - provides an exact way to convert floats to rationals - is (or is intended to be <wink>) upward-compatible - supports the same (but extended) interface (through function Rats.rat) Irony: When I posted a Dates module, I moaned that automatic coercion got in the way. While beefing up the Rat module, automatic coercion was to the contrary a wonderful thing to have, and indeed its lack for + and * was painful to worm around. I believe the method for worming around that used below is about as clean & general an approach as can be crafted in Python today (if you don't see the problem this is trying to solve, figure out why, e.g., "rat(2,3) - 3.0" and "3.0 - rat(2,3)" both invoke Rat.__coerce__ but do not invoke Rat.__sub__; then consider that "rat(2,3) + 3.0" will invoke Rat.__add__ (with 3.0 as the second argument) but not Rat.__coerce__, while "3.0 + rat(2,3)" will invoke Rat.__coerce__ but not Rat.__add__; on the other hand, 3.0*rat(2,3) and rat(2,3)*3.0 both invoke Rat.__mul__ without going through Rat.__coerce__ first ... __add__ and __mul__ are different from all the others, and from each other). Nevertheless, in both the Dates modules & this one, all the problems could be worked around, so it's hard to whine too much ... just-practicing<grin>-ly y'rs - tim # Rational Numbers # # Supplies function `rat' for creating rational-number objects (RNO). # RNOs support mixed-mode arithmetic (+-*/, pow, unary -), comparisons # (==, <=, etc), coercion (to float, int, long), and hashing (so an RNO # can be used as a dictionary key). In Boolean contexts, an RNO is true # if & only if it's non-zero. # # In mixed-mode arithmetic, ints and longs are converted to rationals, # while rationals are converted to floats. Function `rat' can be used # explicitly to convert a float to an exact rational equivalent. # # Given an RNO r, r is the rational number r.num/r.den. r.den > 0 # always, and r.num and r.den have no non-unit common factor. Along with # the convention that 0 is represented as 0/1, this implies each # mathematical rational has a unique representation as an RNO. .num and # .den are intended to be read-only attributes, so that the module can # maintain these properties. # # RNOs come in two flavors: short rats and long rats. The difference is # solely whether .num and .den are Python integers or long integers. # Short rats will in general run substantially faster, but this is of # limited utility since the size of numerators & denominators tends to # blow up quickly during a chain of rational operations. In addition, # except for comparisons, an operation on short rats may raise an # overflow exception during an intermediate calculation, even if the # final result would be representable as a short rat. The author # recommends not using short rats at all unless you know exactly what # you're doing. # # Function rat accepts these arguments: # rat(long a) returns long rat equal to a # rat(int a) returns short rat equal to a # # rat(long a,long b) returns long rat equal to a/b # rat(long a, int b) returns long rat equal to a/b # rat( int a,long b) returns long rat equal to a/b # rat( int a, int b) returns short rat equal to a/b # # rat(float x) returns long rat a/b exactly equal to x; # if x is bizarre (e.g., NaN or infinity on an IEEE # machine), the result is undefined # # # SOME INTERNAL DETAILS # # The algorithms are obvious, or adapted from Knuth Volume 2. The # slowest part of a rational implementation is gcd calculations, so the # operations are coded "cleverly" to avoid gcd whenever possible, and-- # when gcd can't be avoided --to minimize the size of the operands passed # to gcd. # # Speeding gcd itself is difficult. The speed of gcd depends mostly on # the speed of division. 5 gcd functions are defined here, gcd1 through # gcd5, that vary in their zeal to avoid divisions. No single function # is fastest; instead their speed depends on the size of the operands. # From fastest to slowest, they are: # # for short arguments for larger arguments (up for huge arguments # (Python int) to several thousand bits) (many thousand bits) # ------------------- --------------------------- -------------------- # gcd1 gcd5 gcd4 # gcd2 gcd2 gcd3 # gcd5 gcd1 gcd5 # gcd3 gcd3 gcd2 # gcd4 gcd4 gcd1 # # There is some sense to this <wink>: gcd1 does the most divisions, # but it's also the simplest code. For short arguments, saving the # cost of a short division is overwhelmed by the overhead of executing # more interpreted statements. Contrarily, gcd4 does the fewest # divisions but is the most complex code. Pure binary methods aren't # included here because they were never faster than the division # methods (& I expect this is an artifact of using an interpreter; # also that there's no really efficient way to test the last bit of # a Python long ("x & 1" appears to create a long of x's length, then # cut it back, making a conceptual O(1) operation an O(log x) operation; # maybe "odd(x)" could be a builtin?)). # # gcd is set to gcd2 below, because that's the best compromise for # the size of rationals the author usually works with (usually a few # hundred to a couple thousand bits). Bind gcd to one of the other # routines if your usage is different. import math def rat(*args): if len(args) == 2: return Rat().init( args[0], args[1] ) elif len(args) == 1: arg = args[0] t = type(arg) if t in (type(1), type(1L)): return apply( _rat, coerce(arg,1) ) elif t is not type(1.0): raise TypeError, 'need integer or float argument' # convert float to rational; the method here is exact provided # that math.frexp and math.ldexp are exact (which they should be, # on binary machines) # take care of negative and 0 if arg == 0.0: return _rat(0L,1L) top = bot = 1L if arg < 0.0: top, arg = -top, -arg # now arg > 0, and arg * top / bot == original arg; # maintain that equality as an invariant while scaling # so that 0.5 <= arg < 1 arg, shift = math.frexp( arg ) if shift < 0: bot = bot << (-shift) elif shift > 0: top = top << shift answer = _rat( top, bot ) # now arg in [0.5,1.0), and arg*answer == original arg; # remains to convert arg and multiply by answer; # suck up 28 bits at a time: small enough to fit in an int, # and big enough so that any IEEE double will be done in no # more than 2 iterations top, bot = 0L, 1L while arg: arg28 = math.ldexp(arg, 28) # arg * 2^28 ip = math.floor(arg28) # next 28 bits top, bot = top << 28, bot << 28 top, arg = top + int(ip), arg28 - ip return rat(top,bot) * answer else: raise TypeError, 'need 1 or 2 arguments' # _rat packs top/bot into a rational; it trusts they have no common # factor, that 0 is passed as (0,1), that bot != 0, and that they're both # ints or long ints; this avoids the expensive gcd in Rat.init def _rat( top, bot ): if bot < 0: top, bot = -top, -bot answer = Rat() answer.num, answer.den = top, bot return answer # -------------------- GCD routines -------------------- # as simple as they get def gcd1(a, b): while b: a, b = b, a % b return abs(a) # since the quotient is 1 some 41% of the time, this one tries # to save the division in that common case; gcd5 carries the # idea one more step def gcd2(a, b): a, b = abs(a), abs(b) if a < b: a, b = b, a while b: rem = a - b if rem < b: a, b = b, rem else: a, b = b, rem % b return a # a mix of division & binary methods. a & b are forced odd. Then # if r = a % b is odd, b-r is even. So one of {r,b-r} is even. # Factors of 2 are shifted out of that until it's odd again, and # we do it again with the new odd pair. gcd4 is an extension of # this idea. def gcd3(a, b): a, b, ashift, bshift = abs(a), abs(b), 0, 0 if b == 0: return a if a == 0: return b while a & 1 == 0: a, ashift = a>>1, ashift+1 while b & 1 == 0: b, bshift = b>>1, bshift+1 r = a % b if r & 1: r = b - r a, b = b, r while b: b = b >> 1 while b & 1 == 0: b = b >> 1 r = a % b if r & 1: r = b - r a, b = b, r return a << min( ashift, bshift ) # like gcd3, but takes min(r,b-r) after removing factors of 2. This # guarantees that, after the first iteration, a/b >= 3, so we get # some real benefit out of the division. Alas, the interpreter # overhead is high enough that it doesn't actually pay off until the # arguments are over (about, on one particular machine) 10,000 bits long. def gcd4(a, b): a, b = abs(a), abs(b) if a == 0 or b == 0: return max(a,b) ash = bsh = 0 mask = 1L while (a & mask) == 0: mask, ash = mask<<1, ash+1 mask = 1L while (b & mask) == 0: mask, bsh = mask<<1, bsh+1 a, b = a>>ash, b>>bsh if a < b: a, b = b, a r = a % b while r: r2 = b - r mask, rsh = 2L, 1 if r & 1: while (r2 & mask) == 0: mask, rsh = mask<<1, rsh+1 r2 = r2 >> rsh else: while (r & mask) == 0: mask, rsh = mask<<1, rsh+1 r = r >> rsh a, b = b, min(r,r2) r = a % b return b << min(ash,bsh) # carrying gcd2 one more step, to avoid division when the quotient is # 1 (about 41% of the time) or 2 (about 17% of the time) def gcd5(a, b): a, b = abs(a), abs(b) if a < b: a, b = b, a while b: rem = a - b if rem < b: a, b = b, rem else: rem = rem - b if rem < b: a, b = b, rem else: a, b = b, rem % b return a gcd = gcd2 # see comments at the start # return (l, ma, mb) where # l is the least common multiple of a and b # ma * a = l # mb * b = l def lcm(a, b): g = gcd( a, b ) ma, mb = b/g, a/g return ma * a, ma, mb # -------------------- class Rat -------------------- class Rat: def init(self, num, den): num, den = coerce( num, den ) if type(num) not in (type(0), type(0L)): raise TypeError, 'rational must have integer components' if den < 0: num, den = -num, -den elif den == 0: raise ZeroDivisionError, 'rat(x, 0)' g = gcd(num, den) self.num = num/g self.den = den/g return self def __repr__(self): if self.den != 1: return 'rat' + `self.num, self.den` return 'rat(' + `self.num` + ')' def __cmp__(a, b): # relies on denominators being non-negative try: return cmp( a.num*b.den, a.den*b.num ) except OverflowError: return cmp( long(a.num)*b.den, long(a.den)*b.num ) def __hash__(self): return hash(self.num) ^ hash(self.den) def __float__(self): return float(self.num) / float(self.den) def __long__(self): return long(self.num) / long(self.den) def __int__(self): return int(self.num / self.den) def __coerce__(a, b): t = type(b) if t is type(a) and b.__class__ is Rat: return a, b if t is type(0): return a, rat(b, 1) if t is type(0L): return a, rat(b, 1L) if t is type(0.0): return a.__float__(), b return None def __nonzero__(self): return self.num != 0 # Automatic coercion may not take place for + and *, so we check the # type of b and force coercion if it's not Rat. Note that after # coercion, there's still no guarantee that the type of b is Rat (or # the type of a!), since type(coerce(Rat,float)) is float. We worm # around that by reissuing the operation, letting Python figure out # how to do it. def __add__(a, b): if type(b) is type(a) and b.__class__ is Rat: g = gcd( a.den, b.den ) if g == 1: return _rat( a.num*b.den + b.num*a.den, a.den*b.den ) adenoverg = a.den/g top = a.num*(b.den/g) + b.num*adenoverg g2 = gcd( top, g ) return _rat( top/g2, adenoverg * (b.den/g2) ) a, b = coerce( a, b ) return a + b def __mul__(a, b): if type(b) is type(a) and b.__class__ is Rat: g1, g2 = gcd(a.num,b.den), gcd(a.den,b.num) return _rat( (a.num/g1)*(b.num/g2), (a.den/g2)*(b.den/g1) ) a, b = coerce( a, b ) return a * b def __sub__(a, b): return a.__add__( -b ) def __div__(a, b): if b.num: return a.__mul__( _rat( b.den, b.num ) ) raise ZeroDivisionError, 'rational division by 0' def __neg__(self): a = Rat() a.num, a.den = -self.num, self.den return a def __pow__(a, n): if n.den == 1: n = n.num if n < 0: a, n = 1/a, -n return _rat( pow(a.num,n), pow(a.den,n) ) raise ValueError, 'rational raised to non-integer power' # -------------------- tests -------------------- RatTestError = 'RatTestError' def test(): for args, rep in ( ((0,),'0'), ((0L,),'0L'), ((12L,),'12L'), ((12,),'12'), ((-12L,),'-12L'), ((-12,),'-12'), ((144L,12L),'12L'), ((6,9),'2, 3'), ((-6,9),'-2, 3'), ((6,-9),'-2, 3'), ((-6,-9),'2, 3') ): got = `apply(rat, args)` want = 'rat(' + rep + ')' if got != want: raise RatTestError, ('__repr__', got, want) a = rat(37,8) got = `int(a), long(a), float(a), rat(-float(a))` want = '(4, 4L, 4.625, rat(-37L, 8L))' if got != want: raise RatTestError, ('coercion', got, want) a = rat(1, 10) b = rat(2, 5) l = [a+b, a-b, a*b, a/b, pow(-b, 1/a)] want = [rat(1,2), rat(-3,10), rat(1,25), rat(1,4), rat(1024,pow(5,10)) ] if l != want: raise RatTestError, ('arithmetic', l, want) l.sort() want = [rat(-3,10), rat(1024,pow(5,10)), rat(1,25), rat(1,4), rat(1,2)] if l != want: raise RatTestError, ('sort', l, want) if not a or not b or (a+b)*(a-b)-(pow(a,2)-b*b): raise RatTestError, 'boolean context' d = { rat(2): 'two', rat(-12L,16L): rat(4L,8L) } if d[ pow( d[rat(16,7)*rat(21,-64)], -1 ) ] != 'two': raise RatTestError, 'dictionary' for e in 'rat(1,0)', '5/(rat(4,2)-1/rat(3,6))', 'pow(rat(0),-3)': try: exec( 'print ' + e ) raise RatTestError, ('wanted ZeroDivisionError', e) except ZeroDivisionError: pass for args in ( (), (1,1.0), ({},1), ([],), ('ouch',), (1,2,3) ): try: e = apply( rat, args ) raise RatTestError, ('wanted TypeError', args) except TypeError: pass a = rat( 1<<30 ) a = (a < 1/a) # should not overflow a = rat( 1L, 1<<30 ) if 3+a == a+3 == -(-a-3) == 3-(3-a)+3 == 3-(3+(-a))+3 == \ a*2-a+3 == 3*a-2*a-(-3) == \ ((a/45L + a)*(45L/a + a)-46)/a*rat(45,46) + 3: pass else: raise RatTestError, 'probably implicit conversion' x = 3.0 if x+a == a+x == -(-a-x) == x-(x-a)+x == x-(x+(-a))+x == a-x+2*x: pass else: raise RatTestError, 'probably implicit float conversion' sum = rat(-2L,3) for i in range(1,30): sum = sum + pow(-1,i)*rat(i,i+1) want = rat(-446993812891L, 332727080400L) if sum != want: raise RatTestError, ('sum', want, sum) for i in range(1,30): sum = sum - pow(-1,i)*rat(i,i+1) if sum*3 != -2: raise RatTestError, ('sum not -2/3', sum) # test() >>> END OF Rat.py Received: from hopscotch.ksr.com by charon.cwi.nl with SMTP id AA27619 (5.65b/3.10/CWI-Amsterdam); Fri, 27 Aug 1993 11:39:48 +0200 Received: from ksr.com (frankenstein.ksr.com) by hopscotch.ksr.com with SMTP id AA03445; Fri, 27 Aug 1993 05:16:32 -0400 Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA05897; Fri, 27 Aug 93 05:16:30 EDT Received: by kaos.ksr.com (4.1/KSR-2.0) id AA08191; Fri, 27 Aug 93 05:16:28 EDT Message-Id: <9308270916.AA08191@kaos.ksr.com> To: python-list@cwi.nl, allen@ksr.com Subject: Rats 2 Date: Fri, 27 Aug 93 05:16:27 -0400 From: Tim Peters <tim@ksr.com> Added some stuff to the rational-arithmetic module. Rather than repost, I'll just attach the new part of the docs; happy to mail you a copy of the module on request (& I'll contribute the whole thing to Guido after it settles down). The gee-whiz feature is the new approx method, which permits cutting back a rational with sharp control over the accuracy of, and/or the number of bits used by, the approximation. E.g., as worked out in the example below, you can ask for the most space-efficient rational approximation to pi good to at least one part in N (your choice), or the most accurate rational approximation to pi that fits in B (your choice) bits; etc. think-of-it-as-a-memory-aid-for-335/113<snort>-ly y'rs - tim Tim Peters tim@ksr.com not speaking for Kendall Square Research Corp # add support for rat(rational) (a nop) # add functions shortrat and longrat # add .copy() method # add .__abs__() method # add .approx(maxbits,minp) method ... # rat(rational r) returns r unchanged # # Function shortrat takes the same arguments as rat, but always returns a # short rat (however, it may overflow!). # # Function longrat takes the same arguments as rat, but always returns a # long rat. # # If shortrat or longrat are passed an RNO, the RNO itself is changed. # However, the mathematical _value_ of the RNO does not change, and # neither does its hash value. # # Method r.copy() returns a copy s, such that r == s. # # Method r.approx(maxbits, minp) returns a triple (a,n,p). a is a Rat # approximation to r that may take less storage (and hence run faster in # subsequent computations, provided that the loss of accuracy can be # tolerated). The approximation is the best possible such that # # 1) the numerator and denominator each take no more than `maxbits' bits # # 2) if #1 allows it, the approximation is no worse than 1 part in `minp' # (in other words, abs((a-r)/r) <= 1/minp) # # `maxbits' and `minp' must be numeric types, and both must be >= 0. # Intuitively, minp is a bound on the worst relatively accuracy you're # willing to accept, but in no case will you accept more than maxbits # bits. In more detail: # # A sequence of approximations, a1, a2, a3, ..., r, of increasing storage # size and accuracy, is generated internally. Note that this sequence is # finite, since r itself "approximates" r with perfect accuracy. # # If maxbits == 0, condition #1 is ignored, and if minp > 0 the first # approximation in the list meeting the accuracy request is used. # If minp == 0, condition #2 is ignored, and if maxbits > 0 the last # approximation in the list of size <= maxbits is used. # If both are 0, a == r (albeit after extensive computation ...). # If both are nonzero, if the first approximation in the list meeting # condition #2 also meets #1, that's the one that's used; else the last # one in the list meeting #1 is used. # # As mentioned above, approx returns a triple (a,n,p): # a is the rational approximation described above. # n is max( number_of_bits_in(a.num), number_of_bits_in(a.den) ). # If p is 0, a == r. Else p is an integer > 0 such that # abs((a-r)/r) <= 1/p # (so the approximation is no worse off than 1 part in p). # # An example should help: # # >>> import math, Rat # >>> p = Rat.rat(math.pi) # the exact machine value (NOT exact pi!) # >>> p # this may differ on your machine, & some numbers later too # rat(884279719003555L, 281474976710656L) # >>> p.approx(0,4) # get an approximation good to 1 part in 4 # (rat(3L), 2, 22L) # >>> # 3/1 is the smallest-size approximation good to 1 part in 4; # ... # its biggest piece takes 2 bits (for the numerator, 3); # ... # it's actually good to 1 part in 22 (and note that # ... # 1/abs((pi-3)/pi) ~= 22.19, so 3/1 is indeed good to 1 part in # ... # 22 -- but not to 1 part in 23) # ... p.approx(0,1000000) # get one good to one part in a million # (rat(355L, 113L), 9, 11776665L) # >>> # the 9-bit rat 335/113 does the trick, and note that # ... # 1/abs((pi-355/113)/pi) ~= 11776665.62 # ... p.approx(0,11776665), p.approx(8,11776665) # ((rat(355L, 113L), 9, 11776665L), (rat(22L, 7L), 5, 2484L)) # >>> # note that the second one could not meet the accuracy request, # ... # because the limit on the number of bits would not allow it; # ... # note too that 22/7 is in fact the best possible rational # ... # approximation with numerator and denominator no more than 8 bits # ... p.approx(128,11776666) # slightly tighter accuracy request # (rat(103993L, 33102L), 17, 5436311184L) # >>> # 335/113 wasn't quite good enough to meet the accuracy request, # ... # and we need 8(!) additional bits to get a better rational # ... # approximation (335/113 is indeed a very good approximation) # ... p.approx(31,0) # find best approx that fits in Python ints # (rat(1881244168L, 598818617L), 31, 1955598078002080795L) # >>> Rat.shortrat(p.approx(31,0)[0]) # proving it does fit <wink> # rat(1881244168, 598818617) # >>> Rat.shortrat(p.approx(32,0)[0]) # and 32-bit approx doesn't # Stack backtrace (innermost last): # File "<stdin>", line 1 # File "./Rat.py", line 200 # a.num, a.den = int(a.num), int(a.den) # ValueError: long int too long to convert # >>> end of msg Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA08736 (5.65b/3.10/CWI-Amsterdam); Sat, 4 Sep 1993 00:41:38 +0200 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa02834; 3 Sep 93 18:41 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA26651; Fri, 3 Sep 1993 17:57:11 -0400 Date: Fri, 3 Sep 1993 17:57:11 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199309032157.AA26651@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: python-list@cwi.nl Subject: problems with timemodule.c building Python 0.9.9 on IBM AIX 3.2 Hi - I'm trying to build Python 0.9.9 on an IBM RS/6000 AIX 3.2.2 ( I have 0.9.7b built and running fine, including the GL extensions ) I keep having trouble getting past compiling timemodule.c I have tried several variations of defines, but I have not yet found one that works. Has anyone else had any trouble building 0.9.9 ? ( I'll post a followup with more details later, if no one has the answer off hand, but I've got to run now, and I thought I'ld check to see if someone know the proper AIX Makefile Configuration. ) -Steve Majewski (804-982-0831) <sdm7g@Virginia.EDU> -Univ. of Virginia Department of Molecular Physiology and Biological Physics Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA17039 (5.65b/3.10/CWI-Amsterdam); Sun, 5 Sep 1993 05:49:37 +0200 From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: python-list@cwi.nl Subject: tuple handling, but not a tuple... Date: Sat, 4 Sep 93 20:48:51 PDT Message-Id: <9309042048.aa02709@hermix.markv.com> I have a datatype that I would like to be able to do tuple-unpacking on that is NOT a tuple.. I have a phone number type that I would like to assign as: a = NewPhone() a = (areacode, prefix, number, extension) and then be able to do: areacode, prefix, number, extension = a Should I just use a tuple? or is there an easy way to have any custom type use tuple packing and unpacking? Lance Ellinghouse lance@markv.com Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA05903 (5.65b/3.10/CWI-Amsterdam); Mon, 6 Sep 1993 09:48:36 +0200 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa09404; 6 Sep 93 3:48 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA15933; Mon, 6 Sep 1993 03:48:30 -0400 Date: Mon, 6 Sep 1993 03:48:30 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199309060748.AA15933@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: python-list@cwi.nl Subject: Re: problems with timemodule.c builing Python 0.9.9 on IBM AIX > Subject: Re: problems with timemodule.c building Python 0.9.9 on IBM AIX I wrote: > I'm trying to build Python 0.9.9 on an IBM RS/6000 AIX 3.2.2 > ( I have 0.9.7b built and running fine, including the GL extensions ) > I keep having trouble getting past compiling timemodule.c > I have tried several variations of defines, but I have not yet > found one that works. Has anyone else had any trouble building 0.9.9 ? > On Sep 4, 15:30, John DeGood wrote: > I used this successfully on HP-UX 8.07: > > ADDCFLAGS= -DOLDTZ -DNOALTTZD > Thanks. I tried that and several other combinations. > ADDCFLAGS= -DHAVE_STDLIB -DNOALTTZ -DOLDTZ Worked the best - it only gave one warning on compile that there was no definition for floatsleep, and it was changing the declaration (from static) to extern. It later bombed out on linking when it couldn't find floatsleep. If I tried defining 'unix' or BSD_TIME, so that one of the function definitions would be compiled, I got a pageful of other errors. Finally, I copied the floatsleep definition from the "#ifdef unix" block, into a (new) "#ifdef AIX" block, and compiled with: >ADDCFLAGS= -DHAVE_STDLIB -DNOALTTZ -DOLDTZ -DAIX And this seems to work. -Steve Majewski (804-982-0831) <sdm7g@Virginia.EDU> -Univ. of Virginia Department of Molecular Physiology and Biological Physics Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA23416 (5.65b/3.10/CWI-Amsterdam); Tue, 7 Sep 1993 18:32:39 +0200 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa03445; 7 Sep 93 12:32 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA22476; Tue, 7 Sep 1993 12:32:22 -0400 Date: Tue, 7 Sep 1993 12:32:22 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199309071632.AA22476@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: python-list@cwi.nl Subject: another problem building python 0.9.9 on AIX 3.2.2 Well - I got timemodule to compile. The entire build process completes without any errors, and I have an executable python 0.9.9 image, but when I try to import posix it get: ImportError: no module named posix I can't run the regression tests because of the error, but other things that don't import posix appear to work. ( I was building 0.9.9 so I could use some of the new Class features, and I was playing around with these for an evening before I decided to run the tests before trying to rebuild with X11 and GL support. ) posixmodule.c compiles without any error messages and it is linked into the image. my ADDCFLAGS are: ADDCFLAGS= -DHAVE_STDLIB -DNOALTTZ -DOLDTZ -DAIX ( The AIX is defined for my kludge to get timemodule to compile - see previous message. ) - Steve Majewski Received: from ansjovis.cwi.nl by charon.cwi.nl with SMTP id AA23791 (5.65b/3.10/CWI-Amsterdam); Tue, 7 Sep 1993 18:40:48 +0200 Received: by ansjovis.cwi.nl with SMTP id AA17988 (5.65b/3.8/CWI-Amsterdam); Tue, 7 Sep 1993 18:40:47 +0200 Message-Id: <9309071640.AA17988=sjoerd@ansjovis.cwi.nl> To: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Cc: python-list@cwi.nl Subject: Re: another problem building python 0.9.9 on AIX 3.2.2 In-Reply-To: Your message of Tue, 07 Sep 1993 12:32:22 -0400. <199309071632.AA22476@elvis.med.Virginia.EDU> Date: Tue, 07 Sep 1993 18:40:45 +0200 From: Sjoerd Mullender <Sjoerd.Mullender@cwi.nl> On Tue, Sep 7 1993 "Steven D. Majewski" wrote: > Well - I got timemodule to compile. > The entire build process completes without any errors, and I have > an executable python 0.9.9 image, but when I try to import posix > it get: > ImportError: no module named posix > > I can't run the regression tests because of the error, but > other things that don't import posix appear to work. > ( I was building 0.9.9 so I could use some of the new Class > features, and I was playing around with these for an evening > before I decided to run the tests before trying to rebuild > with X11 and GL support. ) > > posixmodule.c compiles without any error messages and > it is linked into the image. > > my ADDCFLAGS are: > ADDCFLAGS= -DHAVE_STDLIB -DNOALTTZ -DOLDTZ -DAIX > > ( The AIX is defined for my kludge to get timemodule to compile - > see previous message. ) > > > - Steve Majewski Apparently USE_POSIX didn't get defined in config.c. You can have a look there to see under which circumstances USE_POSIX is defined. My guess is that "unix" is not defined. I suppose that the ifdefs in config.c should be improved, but for the time being you can try defining "unix" yourself, or change config.c to check for another value. Sjoerd Mullender CWI, dept. CST, Kruislaan 413, 1098 SJ Amsterdam, Netherlands email: Sjoerd.Mullender@cwi.nl fax: +31 20 592 4199 phone: +31 20 592 4127 telex: 12571 mactr nl Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA28411 (5.65b/3.10/CWI-Amsterdam); Tue, 7 Sep 1993 21:00:29 +0200 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa28893; 7 Sep 93 15:00 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA25297; Tue, 7 Sep 1993 15:00:12 -0400 Date: Tue, 7 Sep 1993 15:00:12 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199309071900.AA25297@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: Sjoerd Mullender <Sjoerd.Mullender@cwi.nl> Subject: config.c, Makefile, Configure.py, etc. ( was: problem ... on AIX ) Cc: python-list@cwi.nl, Guido.van.Rossum@cwu.nl On Sep 7, 18:40, Sjoerd Mullender wrote: > > Apparently USE_POSIX didn't get defined in config.c. You can have a > look there to see under which circumstances USE_POSIX is defined. My > guess is that "unix" is not defined. I suppose that the ifdefs in > config.c should be improved, but for the time being you can try > defining "unix" yourself, or change config.c to check for another > value. > Thanks. That was the problem. But the other problem is that defining unix (globally) makes timemodule.c unable to compile. So (one more kludge!) I defined it in the makefile here: >config.o: config.c Makefile libpython.a > $(COMPILE) $(CONFIGDEFS) $(CONFIGINCLS) -Dunix $*.c and "import posix" works and: >make test > PYTHONPATH=../lib ./python -c 'import autotest' >All tests OK. Note: unix is not automatically defined for AIX, so I didn't undef it for timemodule.c Is there anyone else out there building/using python on AIX ? ( I know there are someother UVA folks on this list. ) Is anyone else running into problems with make or ./Configure.py for 0.9.9 ? Most of the problems I've run into are minor, but I'ld like to help Guido sort them out before he gets to the 1.0 release. The other glitch I ran into ( besides posix and the timemodule ) was that, when I did NOT select X11 support in ./Configure.py, the Makefile did not comment out those lines properly, i.e. : >#XT_OBJ= Xtmodule.o Xttypes.o GCobject.o Fontobject.o \ > widgetobject.o wclassobject.o > >#XT_SRC= Xtmodule.c Xttypes.c GCobject.c Fontobject.c \ > widgetobject.c wclassobject.c which 'make' didn't much care for, instead of: >#XT_OBJ= Xtmodule.o Xttypes.o GCobject.o Fontobject.o \ ># widgetobject.o wclassobject.o > >#XT_SRC= Xtmodule.c Xttypes.c GCobject.c Fontobject.c \ ># widgetobject.c wclassobject.c FY( Guido's mostly )I: A long time ago, Guido asked me (and the list, I think) what symbols were automatically defined in AIX. I didn't answer at the time, because I wasn't sure myself. It turns out that most of the "automatic" definitions are defined by a configure file ( /etc/xlc.cfg ), and are different according to which compiler 'alias' is used ( xlc, cc, c89, bsdcc ). This file is user configurable ( UVA has added 'bsdcc' to the standard file - it is in the xlc manual, but not in the standard cfg file.) "_AIX" appears to be the "standard" predefined symbol. My 'gcc' also appears to define "_AIX" , but I don't know if this is standard, or has been modified here at UVA. ( And the RT C compiler predefines "AIX" and "unix" , but not "_AIX" ! ) I have seen a lot of portable Makefile's set ARCH via `uname` - ( which seems to be more standard than SunOS `arch' ) and then use that to define it explicitly in CFLAGS. ( Which is how I've gotten into the habit of often using "#ifdef aix" instead of the "standard" "#ifdef _AIX" . ( If you want to know why something compiles under 'cc', but not c89 ) Here is my /etc/xlc.cfg which is (I think) the same as the standard AIX 3.2.2 distribution except for the addition of 'bsdcc'. language level causes some other defines ( e.g. "-qlanglevl=extended" causes __EXTENDED__ to be defined. ) and also changes the language accepted by the compiler. * @(#) xlc.cfg 1.2 12/19/91 19:30:55 * * COMPONENT_NAME: (CC) AIX XL C Compiler/6000 * * FUNCTIONS: C Configuration file * * ORIGINS: 27 * * (C) COPYRIGHT International Business Machines Corp. 1989, 1990, 1991 * All Rights Reserved * Licensed Materials - Property of IBM * * US Government Users Restricted Rights - Use, duplication or * disclosure restricted by GSA ADP Schedule Contract with IBM Corp. * * standard c compiler xlc: use = DEFLT crt = /lib/crt0.o mcrt = /lib/mcrt0.o gcrt = /lib/gcrt0.o libraries = -lc proflibs = -L/lib/profiled,-L/usr/lib/profiled options = -H512,-T512,-D_ANSI_C_SOURCE,-qansialias * standard c compiler aliased as cc cc: use = DEFLT crt = /lib/crt0.o mcrt = /lib/mcrt0.o gcrt = /lib/gcrt0.o libraries = -lc proflibs = -L/lib/profiled,-L/usr/lib/profiled options = -H512,-T512,-qlanglvl=extended,-qnoro * standard c compiler aliased as c89 c89: use = DEFLT crt = /lib/crt0.o mcrt = /lib/mcrt0.o gcrt = /lib/gcrt0.o libraries = -lc proflibs = -L/lib/profiled,-L/usr/lib/profiled options = -H512,-T512,-D_ANSI_C_SOURCE,-qansialias * common definitions DEFLT: xlc = /usr/lpp/xlc/bin/xlcentry as = /bin/as ld = /bin/ld options = -D_IBMR2,-D_AIX,-bhalt:4 ldopt = "b:o:e:u:R:H:Y:Z:L:T:A:V:k:j:" * bsdcc setup from the porting guide bsdcc: use = DEFLT crt =/lib/crt0.o mcrt =/lib/mcrt0.o gcrt =/lib/gcrt0.o libraries = -lbsd, -lc proflibs = -L/lib/profiled,-L/usr/lib/profiled options = -H512,-T512,-qlanglvl=extended,-qnoro,-D_BSD,-D_NONSTD_TYPES,-D_NO_PROTO,-D_BSD_INCLUDES,-bnodelcsect,-U__STR__,-U__MATH__ -Steve Majewski (804-982-0831) <sdm7g@Virginia.EDU> -Univ. of Virginia Department of Molecular Physiology and Biological Physics Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA29961 (5.65b/3.10/CWI-Amsterdam); Tue, 7 Sep 1993 22:01:47 +0200 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa09776; 7 Sep 93 16:01 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA22402; Tue, 7 Sep 1993 16:01:21 -0400 Date: Tue, 7 Sep 1993 16:01:21 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199309072001.AA22402@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: python-list@cwi.nl Subject: another change for compiling python0.9.9 on AIX ( Fontmodule.c/X11 ) The AIX C compiler does not appear to like this pair of declarations in Fontobject.c ( when compiling with X11 option ): >extern typeobject Fonttype; /* Really static forward */ [ ... ] >static typeobject Fonttype = { [ ... ] and complains about the redefinition. substitute the following. #ifdef _AIX static typeobject Fonttype; /* Really static FORWARD */ #else extern typeobject Fonttype; /* Really STATIC forward */ #endif - Steve Majewski Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA07399 (5.65b/3.10/CWI-Amsterdam); Wed, 8 Sep 1993 09:35:46 +0200 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa04033; 8 Sep 93 3:35 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA12912; Wed, 8 Sep 1993 03:35:37 -0400 Date: Wed, 8 Sep 1993 03:35:37 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199309080735.AA12912@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: python-list@cwi.nl Subject: Thoughts and proposals about types and classes. I've been Reading the rational class posted by Tim Peters and some of the new Class documentation and trying out some of the new (or newly documented) features. Here are a few proposals for consideration. Long ago, I had a few gripes about the python type system, but at that time they were more theoretical than practical. All of the new Class capabilities now make that complaint more practical: The python type system is too narrow for builtin types, and too broad for classes and instances ( where *everything* is <type 'class'> or <type 'instance>' ). For example: with numeric types, we are often not interested in their actual type - that's why there is type coercion. We just what to check that an argument is, in fact, a numeric type of some sort. For builtin types, we can check: "if type( arg ) in ( type(0), type( 0L ), type( 0.0 ) ) :" But this does not extend to user written classes like Complex or Rat. One approach would be to create a new convention that all numeric classes ( That is all classes that define methods for ( __add__, __sub__, ..., __neg__, ... , __int__, __long__, __float__ ) - all the standard numeric methods, and where the semantics of those methods are something that would be considered numeric ( NOT '+' for string concatenation, for example. ) define an attribute "__isnumeric__ " . A function: 'isnumeric', would check for either builtin numeric types or class instances with __isnumeric__ defined. This would probably be a builtin, but a python version is: --------------begin----------- #!/usr/local/bin/python # # the version kludge is because I have msdos version 0.9.8 at home, # unix version 0.9.7b installed on Sun + AIX, and 0.9.9 experimentally # in use under AIX. # import string import sys attr = '_isnumeric_' # '__isnumeric__' is Read Only ver = string.split( sys.version )[0] if ( ver >= '0.9.9' ): def isnumeric(obj): if type(obj) in ( type(0), type(0L), type(0.0) ) : return 1 elif hasattr( obj, attr ) : return getattr( obj, attr ) else: return 0 else: def isnumeric(obj): if type(obj) in ( type(0), type(0L), type(0.0) ) : return 1 try: return getattr( obj, attr ) except ( NameError, TypeError ): return 0 def number( obj ): if isnumeric( obj ): print `obj` + ' is a number.' else: print `obj` + ' is NOT a number.' def test(): class TestNumb: _isnumeric_ = 0 def init(self): self._isnumeric_ = 1 return self N = TestNumb().init() number( 1 ) number( 1L ) number( 1000.0 ) number( 'this string' ) number( type( 0L ) ) number( TestNumb ) number( N ) test() -------------end------------- I'm not sure that I digested and understood all of the previous discussion between Jaap and Guido about instance vs class attributes. From looking at some of the 0.9.9 changes, it looks as if some of the semantics may have been changed in the light of that discussion. I may be wrong. But this brings up the question of whether the __numeric__ attribute should be a class attribute or an instance attribute. It is the instance which is numeric, NOT the class - but it doesn't look quite right to create a new instance attribute ( with the identical value ) for each instance. I suppose the solution is to make it a function/method, which returns 0 or 1, rather than a value attribute. Then it is in the class namespace but responds as an instance method. The same conventions could be followed for '__issequence__' and '__ismapping__' ( It is the ability to override operators like '+' or `[indx]' or '[i:j]' for user defined types that makes the limits of type() more obvious. ) If the typeing of builtin's is too narrow, then the typing of user instances is too broad. Everything is '<type class>' or '<type instance>'. ( I guess I don't really have a problem with '<type class>', but '<type 'instance'>' is not very useful.) One idea would be to make 'type' of user instances programmable just like 'repr'. If I want two classes to be "equivalent" , then I just define their type strings to be identical. How fixed is the notion that type(thing) is a single value? Perhaps type should be a 2-tuple of ( most-restrictive-type, least- restrictive-type ) type( 0 ) ==> ( <type 'int'>, <type 'numeric'> ) type( 1.0 ) ==> ( <type 'float'> , <type 'numeric'> ) type( [] ) ==> ( <type 'list' >, <type 'sequence' > ) type( (1,2) ) ==> ( <type 'tuple' >, <type 'sequence' > ) Since equality comparison works on tuples, "type(agr) == type( [] )" would still work. But "type(type(None))" would no longer be <type 'type'>, it would become '<type 'tuple' > instead. Also: when you try to fit user instances into this scheme, they are: (extremely) generically: instances specifically: instances of some Class (moderately) generically: possibly of some type "family" ( numeric, sequence, iosource, iosink, ... ) Maybe there should be functions 'type()' and 'typefamily()' ? Where typefamily() => number | sequence | mapping, for builtins, and whatever __typefamily__(self) returns for user defined instances, or type(self) if undefined. More ambitious perhaps, might be an entire type hierarchy, with base class types automatically added to the list: "if type(thing) in typeset( object ): " where typeset(obj) yields a tuple built from object's class + base class type strings ( something more specific than: ) + <type 'instance'> OR a builtin tuple ( for example: ( <type 'int'>, <type 'number'> ) ) ( Actually - that doesn't sound so bad. It require one more builtin function + one more attribute for both builtin and user defined objects, it doesn't break anything that uses 'type()', and it's general enough to make "type inheritance" usable. What do you think? ) What sort of approach would make the best fit with python? -Steve Majewski (804-982-0831) <sdm7g@Virginia.EDU> -Univ. of Virginia Department of Molecular Physiology and Biological Physics Received: from schelvis.cwi.nl by charon.cwi.nl with SMTP id AA10225 (5.65b/3.10/CWI-Amsterdam); Wed, 8 Sep 1993 11:30:52 +0200 Received: by schelvis.cwi.nl with SMTP id AA21144 (5.65b/3.8/CWI-Amsterdam); Wed, 8 Sep 1993 11:30:51 +0200 Message-Id: <9309080930.AA21144=jack@schelvis.cwi.nl> To: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Cc: python-list@cwi.nl Subject: Re: another problem building python 0.9.9 on AIX 3.2.2 In-Reply-To: Message by "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> , Tue, 7 Sep 1993 12:32:22 -0400 , <199309071632.AA22476@elvis.med.Virginia.EDU> Organisation: Multi-media group, CWI, Kruislaan 413, Amsterdam Phone: +31 20 5924098(work), +31 20 5924199 (fax), +31 20 6160335(home) X-Last-Band-Seen: Kliek, Lyres (Sleepin, 2-9) X-Mini-Review: Groovy sixties, man.... Date: Wed, 08 Sep 1993 11:30:51 +0200 From: Jack Jansen <Jack.Jansen@cwi.nl> Steve, have you looked at your sys.path? If that looks correctly, you could try something like: import sys for pn in sys.path: fn = pn + '/posix.py' try: fp = open(fn, 'r') print 'Success with', fn except: print 'failed with', fn At least that will tell you that the files really exist, and are readable to python. -- Jack Jansen | If I can't dance I don't want to be part of Jack.Jansen@cwi.nl | your revolution -- Emma Goldman uunet!cwi.nl!jack G=Jack;S=Jansen;O=cwi;PRMD=surf;ADMD=400net;C=nl Received: from schelvis.cwi.nl by charon.cwi.nl with SMTP id AA10317 (5.65b/3.10/CWI-Amsterdam); Wed, 8 Sep 1993 11:35:01 +0200 Received: by schelvis.cwi.nl with SMTP id AA21197 (5.65b/3.8/CWI-Amsterdam); Wed, 8 Sep 1993 11:35:00 +0200 Message-Id: <9309080935.AA21197=jack@schelvis.cwi.nl> To: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Cc: Sjoerd Mullender <Sjoerd.Mullender@cwi.nl>, python-list@cwi.nl, Guido.van.Rossum@cwu.nl Subject: Re: config.c, Makefile, Configure.py, etc. ( was: problem ... on AIX ) In-Reply-To: Message by "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> , Tue, 7 Sep 1993 15:00:12 -0400 , <199309071900.AA25297@elvis.med.Virginia.EDU> Organisation: Multi-media group, CWI, Kruislaan 413, Amsterdam Phone: +31 20 5924098(work), +31 20 5924199 (fax), +31 20 6160335(home) X-Last-Band-Seen: Kliek, Lyres (Sleepin, 2-9) X-Mini-Review: Groovy sixties, man.... Date: Wed, 08 Sep 1993 11:34:59 +0200 From: Jack Jansen <Jack.Jansen@cwi.nl> ok, ok, please ignore my previous message. I had temporarily slipped my mind that posix is a builtin module. As Sjoerd just said "Zeg Jack, wat stuur jij nou voor onzin naar de mailinglist??":-) -- Jack Jansen | If I can't dance I don't want to be part of Jack.Jansen@cwi.nl | your revolution -- Emma Goldman uunet!cwi.nl!jack G=Jack;S=Jansen;O=cwi;PRMD=surf;ADMD=400net;C=nl Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA03157 (5.65b/3.10/CWI-Amsterdam); Wed, 8 Sep 1993 20:08:53 +0200 Received: from [138.95.9.34] by gateway.sequent.com (5.61/1.34) id AA01516; Wed, 8 Sep 93 11:09:44 -0700 Received: from ushqgw1.sequent.com by relay1.sequent.com (5.65/crg/11) id AA27827; Wed, 8 Sep 93 11:13:56 -0700 Received: by ushqgw.sequent.com with Microsoft Mail id <2C8E1FD8@ushqgw.sequent.com>; Wed, 08 Sep 93 11:09:28 PDT From: "Jaap Vermeulen (jaap)" <jaap@sequent.com> To: python-list <python-list@cwi.nl>, "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Subject: RE: Thoughts and proposals about types and classes. Date: Wed, 08 Sep 93 11:07:00 PDT Message-Id: <2C8E1FD8@ushqgw.sequent.com> Encoding: 40 TEXT X-Mailer: Microsoft Mail V3.0 Just a quick comment on Steve's message about type(). I feel that Python may be headed for a rat-hole. Currently we are mixing the procedural-based paradigm with the OO paradigm. To implement procedures, such as len(), we add the __len__ method to user classes. I understand the reasons for doing so (speed, complexity, space, attainable), but it seems backwards. Even by not opening up the builtin objects, it seems more intuitive to implement all functions as methods ('some_string'.len()), at the expense of space (backwards compatibility would be a breeze). For user objects, Python should provide a set of base classes to have a more common framework to start from. Steve's problem has been solved in Smalltalk, where the class hierarchy spells out one aspect of the type() functionality ('isKindOf' method), and generalization addresses the other aspect ('species' method). I'm not saying that this is *the* solution, but it is certainly more intuitive. Comments? | I'm not sure that I digested and understood all of the previous | discussion | between Jaap and Guido about instance vs class attributes. From | looking | at some of the 0.9.9 changes, it looks as if some of the | semantics may | have been changed in the light of that discussion. I may be wrong. Just to clarify the current behavior of Python (0.9.9) w.r.t. class vs. instance variables and methods: o You can use either instance variables or class variable. When you use class variables, you can refer to them in any subclass and the variables will be looked up by searching the base classes (i.e. instance.__class__.variable) o Only instance and unbound methods are supported. Class methods are impossible in the current implementation. -Jaap- Received: from trevnx.BIO.dfo.ca by charon.cwi.nl with SMTP id AA06866 (5.65b/3.10/CWI-Amsterdam); Wed, 8 Sep 1993 21:52:34 +0200 Received: by trevnx.bio.dfo.ca (NX5.67c/NX3.0M) id AA14806; Wed, 8 Sep 93 16:52:31 -0300 Date: Wed, 8 Sep 93 16:52:31 -0300 From: George White 6-8509 <gwhite@trevnx.bio.dfo.ca> Message-Id: <9309081952.AA14806@trevnx.bio.dfo.ca> To: python-list@cwi.nl Subject: Python 0.9.9 runs on NeXT (black, 3.0, mouse-X) Like many people, I'm looking at tools to help my Internet grazing, provide better documentation, etc. It wasn't hard getting stdwin 0.9.8 and python 0.9.9 to run under NS 3.0. I used Mouse-X libraries (no Motif) but run X clients on an NCD X-terminal rather than the Mouse-X server. Compilation details: I followed the suggestion to make a basic version of python in order to use the interactive configuration. The hardest part was remembering the "-m" flag to permit linking with the provided version of strtol.c because the first attempt (using NeXT's strtol) didn't pass the "make test" tests. $ grep "^[^#]" Makefile CFLAGS= $(THREAD_USE) $(ADDCFLAGS) $(X11_INCL) ARCH= next CC= cc AR= ar ADDCFLAGS= WAITDEF= -DNO_WAITPID LIBMATH= -lm DESTDIR=/usr/local BINDESTDIR=$(DESTDIR)/bin BINDEST=$(BINDESTDIR)/python MANDESTDIR=$(DESTDIR)/man/man1 MANDEST=$(MANDESTDIR)/python.1 LIBDESTDIR=$(DESTDIR)/lib LIBDEST=$(LIBDESTDIR)/python DOCDEST=$(LIBDEST)/doc DEMODEST=$(LIBDEST)/demo DEFPYTHONPATH= .:$(LIBDEST):$(LIBDEST)/$(ARCH) STRERROR_SRC= strerror.c STRERROR_OBJ= strerror.o FMOD_SRC= fmod.c FMOD_OBJ= fmod.o STRTOL_SRC= strtol.c STRTOL_OBJ= strtol.o GETCWD_SRC= getcwd.c GETCWD_OBJ= getcwd.o SIGTYPEDEF= -DSIGTYPE=int BSDTIMEDEF= -DBSD_TIME TIMESDEF= -DDO_TIMES RE_USE= -DUSE_REGEX RE_SRC= regexpr.c regexmodule.c RE_OBJ= regexpr.o regexmodule.o LIBREADLINE= /usr/local/lib/libreadline.a LIBTERMCAP= -ltermcap RL_USE = -DUSE_READLINE RL_LIBS= $(LIBREADLINE) RL_LIBDEPS= $(LIBREADLINE) ADDLIBS=-m # so that we can use strtol.c STDWINDIR= ../../stdwin LIBSTDWIN= $(STDWINDIR)/Build/$(ARCH)/x11/lib/lib.a LIBX11 = -lX11 STDW_INCL= -I$(STDWINDIR)/H STDW_USE= -DUSE_STDWIN STDW_LIBS= $(LIBSTDWIN) STDW_LIBDEPS= $(LIBSTDWIN) STDW_SRC= stdwinmodule.c STDW_OBJ= stdwinmodule.o X11_USE= -DUSE_X11 X11_INCL= X11_LIBDIRS= XT_USE= -DUSE_XT XT_LIBS= -lXmu -lXt -lX11 -lXext XT_OBJ= Xtmodule.o Xttypes.o GCobject.o Fontobject.o \ widgetobject.o wclassobject.o XT_SRC= Xtmodule.c Xttypes.c GCobject.c Fontobject.c \ widgetobject.c wclassobject.c EDITRES_USE= -DUSE_EDITRES XAW_USE= -DUSE_XAW XAW_LIBS= -lXaw XAW_OBJ= Xawmodule.o XAW_SRC= Xawmodule.c HTML_USE= -DUSE_HTML HTML_OBJ= HTMLmodule.o HTML_SRC= HTMLmodule.c HTML_LIBS= /usr/local/lib/libhtmlw.a X11_USE= $(XT_USE) $(XAW_USE) $(XM_USE) $(GLX_USE) $(HTML_USE) X11_LIBS= $(X11_LIBDIRS) \ $(XAW_LIBS) $(XM_LIBS) $(GLX_LIBS) $(HTML_LIBS) $(XT_LIBS) X11_OBJ= $(XT_OBJ) $(XAW_OBJ) $(XM_OBJ) $(GLX_OBJ) $(HTML_OBJ) X11_SRC= $(XT_SRC) $(XAW_SRC) $(XM_SRC) $(GLX_SRC) $(HTML_SRC) FCNTL_USE= -DUSE_FCNTL FCNTL_SRC= fcntlmodule.c FCNTL_OBJ= fcntlmodule.o FCNTL_LIBS= FCNTL_LIBDEPS= DBM_USE= -DUSE_DBM DBM_SRC= dbmmodule.c DBM_OBJ= dbmmodule.o DBM_LIBS= DBM_LIBDEPS= STROP_USE= -DUSE_STROP STROP_SRC= stropmodule.c STROP_OBJ= stropmodule.o STROP_LIBS= STROP_LIBDEPS= IMAGEOP_USE= -DUSE_IMAGEOP IMAGEOP_SRC= imageopmodule.c IMAGEOP_OBJ= imageopmodule.o IMAGEOP_LIBS= IMAGEOP_LIBDEPS= ARRAY_USE= -DUSE_ARRAY ARRAY_SRC= arraymodule.c ARRAY_OBJ= arraymodule.o ARRAY_LIBS= ARRAY_LIBDEPS= A few hacks in posixmodule.c: #ifdef NeXT #define mode_t int #define NO_UNAME #define HZ 60 typedef int clock_t; #endif /* NeXT */ So far I have used the www client, ibrowse, and texi2html as well as a bit of interactive messing around with no serious unpleasantness. Python certainly looks like something I will use. Thanks to Guido Rossum and crew. /George White <GWhite@BIOnet.BIO.DFO.ca> Bedford Inst. of Oceanography Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA06940 (5.65b/3.10/CWI-Amsterdam); Wed, 8 Sep 1993 21:54:29 +0200 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa00686; 8 Sep 93 15:54 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA20950; Wed, 8 Sep 1993 15:54:04 -0400 Date: Wed, 8 Sep 1993 15:54:04 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199309081954.AA20950@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: python-list@cwi.nl Subject: a buffered input stream class This is a somewhat awkward example of an input stream class. The first half was written for a practical purpose. The main function I needed was the readuntil( delimiter ) method. I'm sure that some of you would just slurp in the whole file and then process it as a string. Well - I may need to process vary large files, I may need to test it on smaller files on my 640K PC at home, but mostly, I would like to keep a sequential flow to the processing. Still, for that requirement, it could be simpler (and faster), but I wanted to play around with python classes. Which leads me to comment on the 2nd half - which was tacked on later as an experiment. One result of the experiment was discovering that my attempt at a "string index" for a sequence didn't work : the index can only be an int! Initially, I was going to add a version of readuntil where delimiter could be a regexp. Then, after I started playing around with getslice, I thought it would be neat to be able to write "stream[0:regexp]" and have it return from the current position thru till the end of the regexp. But now that I know stream[0:'\n'] won't work, I'll go back to stream.readuntil( ) No effort has been made to optimize the reads or the copying assignments, except some slight effort to avoid reading in the whole file. ( And in one place I break that rule too - I was in a hurry to finish and use it! ) But it's more fodder for discussion of Classes and Types in python. It (mostly) works on posix.popen input pipes, but it doesn't yet work exactly the way I want it to. That's 'cause it isn't yet written to do what I want yet. ( I probably need to read with a timeout, so that it will only read in what's available. I don't know if I will pursure this - it's not necessary for me at the moment. ) So you will hang on len( pipestream ), for example, if the output is not complete. I would like to process only up to what is immediately available. But I *have* noticed an anomaly with how the read method handles EOF from the terminal: >>>sys.stdin.read( 2 ) \n \n returns => '\012\012' >>>sys.stdin.read(2) ^D returns immediately => '' >>>sys.stdin.read(2) \n ^D \n finally returns with => '\012\012' Maybe this is a 'feature' of gnu-readline ? And - while on the subject of 'read' - I was considering trying the new array module if I make an attempt to optomize the istream module, and I noticed that the read and write methods in the array module are "backwards" compared to the other read methods: array_obj.read( file_obj, count ) vs. string = file_obj.read( nchars ) The reason this is so is clear. But maybe array_obj.read() should be array_obj.readfrom() ? ( Am I pursuing a foolish consistency here? ) -- Steve Majewski ---------- #!/usr/local/bin/python # import string numeric_types = ( type(0), type(0L), type(0.0) ) class IStream: def __init__( self, source ): self.buffer = [] self.indx = 0 self.source = source self._bsize = 1024 def next( self ): if ( self.indx == len( self.buffer )) : self.buffer = self.source.read( self._bsize ) self.indx = 0 self.indx = self.indx + 1 return self.buffer[self.indx-1:self.indx] def readuntil( self, delim ): temp = '' c = None while( '' <> c <> delim ): c = self.next() temp = temp + c return temp def pushback( self, oldstring ): self.buffer = oldstring + self.buffer[self.indx:] self.indx = 0 return None # note: all of the "sequential" methods will "sequentialize" the stream - # i.e. set start of buffer to indx, and possibly read in more ( or the # entire stream ). def _normal_( self ): if len(self.buffer) == 0 : self.buffer = self.source.read( self._bsize ) self.indx = 0 elif ( self.indx <> 0 ): self.buffer = self.buffer[self.indx:] + self.source.read( self._bsize ) self.indx = 0 def _readall_( self ): self._normal_() tmp = self.source.read( self._bsize ) while ( tmp <> '' ): self.buffer = self.buffer + tmp tmp = self.source.read( self._bsize ) def __len__( self ): self._readall_() return len( self.buffer ) def __getitem__( self, key ): self._normal_() if ( 0 <= key > len(self.buffer) ): self.buffer = self.buffer + self.source.read( key - len(self.buffer) ) else: self._readall_() return self.buffer[key] def _string_index_( self, k ): if type(k) in numeric_types : return k if type(k) <> type('') : raise IndexError i = string.find( self.buffer, k ) if ( i < 0 ) : self.__readall__() # this should be incremental, not READALL. i = string.find( self.buffer ) if i < 0 : raise IndexError return i def __getslice__( self, i, j ): self._normal_() limit = len( self.buffer ) if type(i) == type('') : i = self._string_index_( i ) if type(j) == type('') : j = self._string_index_( j ) if ( i < 0 ) or ( j < 0 ): self._readall_() m = max( i, j ) if m > limit: m = m - limit self.buffer = self.buffer + self.source.read( m ) return self.buffer[i:j] def goodtest( filename ): S = IStream( open( filename, 'r' ) ) print 'S[0]: ', S[0] print 'S[0:10]: ', S[0:10] print 'for I in range( 1,20 ): S.next(): ' for i in range( 1, 20 ): print S.next(), for i in range( 1, 3 ): print i,': S.readuntil(":")' print S.readuntil(':') x = S.readuntil( '\n' ) print 'x = readuntil( newline ): ' print x S.pushback( x[-3:] ) print 'S.pushback( x[-3:] ); x = readuntil( newline ): ' x = S.readuntil( '\n' ) print x print 'S[0:120]: ', S[0:120] print 'S[-120:]: ', S[-120:] return S def alltest( filename ): S = goodtest( filename ) print '\n*This test will *FAIL*... ' print 'S[0:\'n\']: ... ' print S[0:'\n'] import sys if ( len(sys.argv) > 1 ) : for F in sys.argv[1:] : print ' Filename: ', F alltest( F ) Received: from hopscotch.ksr.com by charon.cwi.nl with SMTP id AA08821 (5.65b/3.10/CWI-Amsterdam); Thu, 9 Sep 1993 09:22:34 +0200 Received: from ksr.com (frankenstein.ksr.com) by hopscotch.ksr.com with SMTP id AA25711; Thu, 9 Sep 1993 03:21:38 -0400 Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA13910; Thu, 9 Sep 93 03:21:35 EDT Received: by kaos.ksr.com (4.1/KSR-2.0) id AA11962; Thu, 9 Sep 93 03:21:31 EDT Message-Id: <9309090721.AA11962@kaos.ksr.com> To: sdm7g@Virginia.EDU, python-list@cwi.nl Subject: Re: Thoughts and proposals about types and classes Date: Thu, 09 Sep 93 03:21:31 -0400 From: Tim Peters <tim@ksr.com> I agree the type system is sometimes clunky in practice, for the reasons you give: the distinctions among built-in types are sometimes too fine, and among (at least conceptually -- is a new class really a new type? hmm) user-defined types often too gross. But I don't have a nice answer. It's always been possible to worm around the perceived clunkiness with what, by any objective measure, is very simple code (albeit perhaps not _obvious_ code, at first; your isnumeric function fits in here), and no Real Simple extension satisfies. E.g., sometimes I want to know whether an object is specifically a plain integer, sometimes any flavor of integer, sometimes any built-in numeric type, and sometimes just whether the object supports something it _calls_ "subtraction" (the Dates module was interesting in this respect, since it's both a real stretch to call a Date object a numeric type, and a real convenience to define _some_ of the numeric operations on Date objects). Quite some time ago, a certain well-known Python wizard favored me with a lucid discussion of some of these issues in E-Mail; I'll reproduce part of that here, without their permission: > >[tim] > >Ha! You can justify > > if type(self) is type(other) and other.__class__ is Complex: > > > >but you can't call it "wonderfully clear" <grin>. Supposing that "type" > >returned a unique type for instances of user-defined classes, and that > >class objects had a __type__ attribute which was the type of instances of > >that class, _this_ would be wonderfully clear: > > > > if type(other) is Complex.__type__: > > > >I'm not in love with that notation, I'm just trying to improve your > >esthetic judgment <wink>. > [a certain well-known python wizard] > Yes, but this has the problem with derived classes explained above. > Maybe I should do it anyway, and also add a simple way to test for > derived classes. > [and "the problem with derived classes explained above"] > ... > Seriously, even though it wouldn't be too hard to introduce a new type > object for each class, I don't know if this would solve too many > problems. I can foresee one new problem: derived classes. Naive code > implementing e.g. complex numbers that tests whether two objects have > the same type will work until someone derives a trivial class... > > Languages like C++ sidestep this issue by not making classes and types > first-class objects. The compiler has a number of tests similar to my > proposed sametype(), e.g. compatible_for_assignment(), etc. > > In Python most tests for type compatibility in the interpreter are > done on a much more pragmatic basis: the only requirement is that an > object supports the operations that are actually applied to it. This > means that you can write "polymorphic" code, which doesn't care > whether the argument to a function has exactly the right type, as long > as it supports the proper operations or has the proper attributes. > For example, it is now possible to substitute a user-defined object > for sys.stdout; the only requirement of this object is that it has a > method "write" taking a string argument. In C++, this is impossible: > a common base class must exist. > > It follows that explicit type checks in Python code should be > exceptions to the rule, and indeed there is often something fishy > whenever type() is called. However, for __coerce__ functions as used > in Complex or Rat there really isn't a serious alternative. I suppose > a cheap way of testing for a subclass would help a little. This > doesn't help in case someone creates a "Complex lookalike" but that > doesn't sound like a big problem in practice (and at least one of the > types could be taught about the other). I've since taken the "the only requirement is that an object supports the operations that are actually applied to it" as a useful design principle, and found that most of my uses of "type" vanished as a result, and that the code became more general even while becoming simpler. A neat example of the latter phenomenon is a rework of the Complex module: by pruning out overly-protective uses of "type", I got a Complex module that works fine for Complex numbers whose real & imaginary parts are arbitrary-precision rationals (or integers, or-- indeed --are Complex themselves: any objects that "support the operations applied to them"). This is slick! "type" is really needed in only a few places, and half of those just to worm around the non-coercion of + and * arguments. So I pretty much stopped worrying about the type system. However, since I'm the primary consumer of the classes I write, I'm happy with obscure error msgs from deep in the bowels of the class implementation; another user would doubtless much rather be told up front "you can't divide a complex by a dictionary" at the top level, and supplying that friendliness would put me right back in the "type" business. Messy issues! > [steve] > Which leads me to comment on the 2nd half ... One result of the > experiment was discovering that my attempt at a "string index" for a > sequence didn't work : the index can only be an int! There are similar (undocumented but certainly not crazy) constraints on numeric operations. E.g., >>> from Rat import rat >>> r=rat(2,3) >>> r/[5] Stack backtrace (innermost last): File "<stdin>", line 1 TypeError: number coercion failed >>> [5]/r Stack backtrace (innermost last): File "<stdin>", line 1 TypeError: bad operand type(s) for / >>> Presumably I could trick the first one into working (whatever that might mean in this context <grin>), but not the latter. I agree it would be a bit nicer if Python didn't constrain the kinds of objects passed to __div__, __getslice__, etc. You can _usually_ worm around these restrictions by disguising the built-in object in a class instance, but I see that doesn't work for __getslice__. On the other hand, __getslice__(s,i,j) is documented as adding len(s) to j if j<0 etc, so there appears to be a good reason for insisting that i & j be ints (i.e., so that "j<0" and "j+len(s)" make sense!). tickled-by-what-you-_wanted_-to-do-with-__getslice__-all-the-same-ly y'rs - tim Tim Peters tim@ksr.com not speaking for Kendall Square Research Corp Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA28564 (5.65b/3.10/CWI-Amsterdam); Thu, 9 Sep 1993 18:25:45 +0200 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa01482; 9 Sep 93 12:25 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA22936; Thu, 9 Sep 1993 12:25:06 -0400 Date: Thu, 9 Sep 1993 12:25:06 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199309091625.AA22936@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: Tim Peters <tim@ksr.com>, sdm7g@virginia.edu, python-list@cwi.nl Subject: Re: Thoughts and proposals about types and classes On Sep 9, 3:21, Tim Peters wrote: > > I've since taken the "the only requirement is that an object supports the > operations that are actually applied to it" as a useful design principle, > and found that most of my uses of "type" vanished as a result, and that > the code became more general even while becoming simpler. > > A neat example of the latter phenomenon is a rework of the Complex > module: by pruning out overly-protective uses of "type", I got a Complex > module that works fine for Complex numbers whose real & imaginary parts > are arbitrary-precision rationals (or integers, or-- indeed --are Complex > themselves: any objects that "support the operations applied to them"). > This is slick! "type" is really needed in only a few places, and half of > those just to worm around the non-coercion of + and * arguments. > > So I pretty much stopped worrying about the type system. However, since > I'm the primary consumer of the classes I write, I'm happy with obscure > error msgs from deep in the bowels of the class implementation; another > user would doubtless much rather be told up front "you can't divide a > complex by a dictionary" at the top level, and supplying that > friendliness would put me right back in the "type" business. Messy > issues! > You're probably right! Doing some upfront error checking on the args to give a coherent error message was actually the primary use I had in mind for a better type/class/subclass test. And even there, I can always wrap the whole thing with a "try: ... ; except TypeError: " to give *MY* error message, rather than the one from "deep in the bowels". But, as in Guido's previous remarks contra-non-qualified-excepts ( Try: ; Except: #(everything) ), in those few cases when I actually KNOW exactly what I want, I would like to be exactly specific, and not worry that I might catch an exception that is not from the expected cause. Also, the info from an exception might not be specific enough ( like WHICH arg was bad? ) unless you first test some guarded commands: for ARG in ARGLIST: try: tmp = ARG + 0 # or perhaps tmp = ARG[0] for sequences except: raise some_more_specific_error I've got code where I DO check for type(()) or type([]). And I would prefer, for just the reasons you state, to not be *overly* restrictive: I probably really mean to test for is_a_mutable_ sequence? , not <type 'list'>. So I'm looking for an easy way to do this. def issequence( s ): if type(s) in ( type(()), type([]) ): return 1 if type(s) <> TypeInstance : return 1 for X in ( '__len__', '__getitem__', '__getslice__' ): if not hasattr( s, X ) : return 0 return 1 is not too bad, but the list gets longer for mutable sequences and numerics. I don't think the convention of having to implement __isnumeric__ or __issequence__ would be too much to ask to make the implementation of issequence() of isnumeric() easier and more effecient. And it would also be a promise of some "reasonable" semantics. ( and like all promises, you should consider the promiser! ) [ That was my minimal & initial proposal - the other ramblings were an effort to see if there was something more general that could be done with the type/class system. ] Your comments about _you_ being the primary consumer of your classes is on the mark. Most of my use of python is when I want a quick ( and possibly dirty ) solution, and I don't really want to bother coding argument checks and error messages. In those cases, python's default behaviour is quite sufficient. But if python actively discourages error checking by making it awkward or difficult or time consuming, then it's use for more ambitious "end user" programs may be limited. [ This brings us back to the "What are YOU using python for" thread. More entries are hereby solicited! ] > > [steve] > > Which leads me to comment on the 2nd half ... One result of the > > experiment was discovering that my attempt at a "string index" for a > > sequence didn't work : the index can only be an int! > [ ... ] > > tickled-by-what-you-_wanted_-to-do-with-__getslice__-all-the-same-ly > y'rs - tim > I can see reasons why it *SHOULDN'T* work - both technical/implementation reasons AND semantic/reasonable-expectation reasons. I was just playing around and was trying to see what I could and couldn't do. I don't want it to be interpreted as a request or complaint that it didn't work. Especially in the light of my pedantic (actual) complaint that array.read( file, count ) OUGHT to be array.readfrom( file, count ) since there should be a reasonable expectation that obj.read() is a method of something that can be "read" and takes an argument of "how much" . ( Or, at least, there *WAS* a reasonable expectation until array objects were added to the language. The counter point-of-view is than no methods except those starting with "__" should be considered "sacred".) I don't think 'seq[int]' is an unreasonable restriction. -Steve Majewski (804-982-0831) <sdm7g@Virginia.EDU> -Univ. of Virginia Department of Molecular Physiology and Biological Physics Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA00419 (5.65b/3.10/CWI-Amsterdam); Thu, 9 Sep 1993 19:04:03 +0200 Received: from [138.95.9.34] by gateway.sequent.com (5.61/1.34) id AA14135; Thu, 9 Sep 93 10:04:54 -0700 Received: from ushqgw1.sequent.com by relay1.sequent.com (5.65/crg/11) id AA12084; Thu, 9 Sep 93 10:08:28 -0700 Received: by ushqgw.sequent.com with Microsoft Mail id <2C8F6208@ushqgw.sequent.com>; Thu, 09 Sep 93 10:04:08 PDT From: "Jaap Vermeulen (jaap)" <jaap@sequent.com> To: python-list <python-list@cwi.nl>, "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu>, sdm7g <sdm7g@virginia.edu>, Tim Peters <tim@ksr.com> Subject: Re: Thoughts and proposals about types and classes Date: Thu, 09 Sep 93 10:02:00 PDT Message-Id: <2C8F6208@ushqgw.sequent.com> Encoding: 12 TEXT X-Mailer: Microsoft Mail V3.0 Error checking (type checking) in code that retrieves information from outside a program seems perfectly valid (user or file input). Type checking to catch programming errors seems counter productive, especially if the error messages are going to be meaningless to the end-user (here the end-user is *not* the programmer). Python does a reasonably job to track down programming errors (the stack trace). $0.02 -Jaap- Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA02225 (5.65b/3.10/CWI-Amsterdam); Thu, 9 Sep 1993 19:50:55 +0200 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa20595; 9 Sep 93 13:50 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA21163; Thu, 9 Sep 1993 13:49:19 -0400 Date: Thu, 9 Sep 1993 13:49:19 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199309091749.AA21163@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: "Jaap Vermeulen (jaap)" <jaap@sequent.com>, python-list <python-list@cwi.nl>, sdm7g <sdm7g@virginia.edu>, Tim Peters <tim@ksr.com> Subject: Re: Thoughts and proposals about types and classes On Sep 9, 10:02, "Jaap Vermeulen (jaap)" wrote: > > Error checking (type checking) in code that retrieves information from > outside a program seems perfectly valid (user or file input). Type checking > to catch programming errors seems counter productive, especially if the > error messages are going to be meaningless to the end-user (here the > end-user is *not* the programmer). Python does a reasonably job to track > down programming errors (the stack trace). > > $0.02 > > -Jaap- > But a Class is just *supposed* to be THAT TYPE of interface. A class method get's it's arguments ( except for "self" ) from "outside". So there are TWO types of error messages: "Something unexpected happened - This class is broken!" - stack trace and other interesting stuff for the implementor (or re-implementor or maintainer) of that class. [for the Class programmer] -OR- "You are giving me garbage! - please read the instructions on how to use this class and/or method." [for the Class end-user] That's largely what OO-design/programming is all about: (isn't it?) The distinction of inside/outside on many different levels; black boxes, interfaces, etc. The programmer IS the end user - of a Class. [ <unrelated-digression-about-error-handlers>: One of the things I used to like about VAX/VMS exceptions was that they also had levels of severity: (Info,Warning,Error,Severe ) and you could raise/catch/ignore signals of a specific level. So instead of using a debug or verbose flag, you would just lower the severity level to catch and report warnings. But the exception handler had a different model than python - after catching a exception signal, you could examine it, and return to the site of the exception - which is exactly what you would want to do for warnings and informational messages. Or re-raise the exception for more uplevel processing. ] - Steve M. BTW: there are a few bugs in my IStream Class. It passed the tests OK on small files, but accessing stream[indx] before the buffer is loaded by some other access seems to make it try to read in the whole file ( which is quite noticable when you try it on a LARGE file. ) Well - I *did* note that it was not_ready_for_prime_time ! I'll post a better version when it's finished ( along with the readuntil( 'string' ) or readuntil( regexp ) additions. Please excuse me for posting alpha code - I just want to keep the discussion moving with some examples. Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA03246 (5.65b/3.10/CWI-Amsterdam); Thu, 9 Sep 1993 20:19:58 +0200 Received: from [138.95.9.34] by gateway.sequent.com (5.61/1.34) id AA17558; Thu, 9 Sep 93 11:20:52 -0700 Received: from ushqgw1.sequent.com by relay1.sequent.com (5.65/crg/11) id AA14470; Thu, 9 Sep 93 11:23:13 -0700 Received: by ushqgw.sequent.com with Microsoft Mail id <2C8F738D@ushqgw.sequent.com>; Thu, 09 Sep 93 11:18:53 PDT From: "Jaap Vermeulen (jaap)" <jaap@sequent.com> To: python-list <python-list@cwi.nl>, "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu>, sdm7g <sdm7g@virginia.edu>, Tim Peters <tim@ksr.com> Subject: Re: Thoughts and proposals about types and classes Date: Thu, 09 Sep 93 11:09:00 PDT Message-Id: <2C8F738D@ushqgw.sequent.com> Encoding: 15 TEXT X-Mailer: Microsoft Mail V3.0 | But a Class is just *supposed* to be THAT TYPE of interface. I tend to disagree. I think the end-user of an application will not care about the internal structure of the application and/or the techniques used to create it. | "You are giving me garbage! - please read the instructions on | how to use this class and/or method." I can sympathize with the reasoning. I guess I would add rigid checking as a debugging tool during development of an application. -Jaap- Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA04108 (5.65b/3.10/CWI-Amsterdam); Thu, 9 Sep 1993 20:41:34 +0200 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa00946; 9 Sep 93 14:41 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA22873; Thu, 9 Sep 1993 14:41:05 -0400 Date: Thu, 9 Sep 1993 14:41:05 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199309091841.AA22873@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: python-list@cwi.nl Subject: istream class bugs As I noted - I found that my IStream class was reading in the entire in some cases. There was a bug which caused it to read the entire class when __getitem__ was the first method used ( and the buffer was therefore initially empty ). That was the easy part to fix. But there is also a problem with __getslice__ - it appears to ALWAYS read in the whole file. This appears to be a side effect of the fact that getslice normalizes negative indexes by subtracting the length. ( I point I hadn't noted at first! ) and it appears that it always calls __len__(), even when the indexes are positive. ( maybe it is also checking if they are in-bounds ? ) Well - that sort of makes that a useless method for the uses I had been considering. Maybe I should go back to the earlier version without the pseudo sequence operation tacked on. The indexing and slicing was really only needed as a sort of 'peek' into the stream. I can just as well add a peek( n ) method or use the pushback() method to do the same thing. -- Steve M. Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA04816 (5.65b/3.10/CWI-Amsterdam); Thu, 9 Sep 1993 21:00:20 +0200 To: python-list@cwi.nl Subject: JPEG module X-Organization: Mark V Systems Ltd. X-Address: 16400 Ventura Blvd Suite 303, Encino, Ca, 91436, USA X-Phone: +1 818 995 7671 (work), +1 818 995 4267 (fax) Date: Thu, 9 Sep 93 11:59:44 PDT From: lance@markv.com Sender: lance@markv.com Message-Id: <9309091159.aa03132@hermix.markv.com> Source-Info: From (or Sender) name not authenticated. Does anyone have the libraries to allow the JPEG module to be used? Where can I grab it from? Does anyone have the same type of module for GIF files? Thank you, -- Lance Ellinghouse lance@markv.com 1231 bit key fingerprint = 56 DA 31 0C 17 51 36 6A 4E D4 E0 11 D9 B8 06 0A 1024 bit key fingerprint = 66 2C 75 F2 E9 1C 32 84 3A E3 B0 5E 48 01 4C 37 You can recieve my Public Key by `finger lance@mark.com` Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA06657 (5.65b/3.10/CWI-Amsterdam); Thu, 9 Sep 1993 21:51:23 +0200 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa14819; 9 Sep 93 15:51 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA20712; Thu, 9 Sep 1993 15:50:43 -0400 Date: Thu, 9 Sep 1993 15:50:43 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199309091950.AA20712@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: "Jaap Vermeulen (jaap)" <jaap@sequent.com>, python-list <python-list@cwi.nl>, sdm7g <sdm7g@virginia.edu>, Tim Peters <tim@ksr.com> Subject: Re: Thoughts and proposals about types and classes steve> But a Class is just *supposed* to be THAT TYPE of interface. jaap> I tend to disagree. I think the end-user of an application will not jaap> care about the internal structure of the application and/or the jaap> techniques used to create it. I agree with that sentence - but it's beside the point. The point I was trying to make was: I think the end-user of an CLASS will not care about the internal structure of the CLASS and/or the techniques used to create it. steve> "You are giving me garbage! - please read the instructions on steve> how to use this class and/or method." jaap> I can sympathize with the reasoning. I guess I would add rigid jaap> checking as a debugging tool during development of an application. Again - the distinction I was trying to make: Type checking and some error checking that was put there to check that the class actually works as it is supposed to, is a debugging tool that can be removed when it has served it's purpose. Which is to show that given the proper input, the class is consistent and correct in it's behaviour. Assuming for the moment that the class is bug free and consistent, it should still give a reasonable error message when it is misused or given the wrong input arguments. To move the interface lines for a moment - what you are saying is rather like: "The program is bug free, so there is no need for error messages - if the users give it the wrong input, it will crash and the OS will tell them it crashed. They can then check their input files and see what THEY did wrong. And even if there IS a bug, they wouln't be interested in the details!" No - the end user is not interested in the details of the program's implementation. But they are interested in the distinction between: 'no such file', 'no privilege to read file', and 'input file incorrect format'. A related question is whether the default error messages are sufficient. In many cases, the error message from 'deep in the bowels' IS going to be the correct one. If it is a TypeError when your try to actually USE the argument, then it was probably going to be a TypeError raised if and when you checked it. When I moved to unix from VMS, I had to adjust my programming style somewhat. I had grown accustomed to the fact the VMS default system error messages and behaviour were usually sufficient that the program didn't need to do as much. The same programs moved to unix gave incomprehensible messages ( or none at all ) And, in fact, the only problem with VMS messages was that they often gave you all of the stack trace and other stuff not needed by the end user. So the usual reason for adding explicit error checking was to REMOVE information that was a distraction to the end-user. 'No such filename' does NOT need a stack trace. Specifically - python's default error behaviour is not bad - the typical reason to change it is the same as in VMS - too MUCH information. In general, I'm saying that there is a distinction to be made between implementor-oriented error messages ( This program/ procedure/class/shell-script/whatever has a BUG ) and end-user oriented error messages ( You are feeding me the wrong imput. ) But in the case of reusable classes, another programmer ( or even the same programmer 6 months later ) is the "end-user" of the class. The same inside/outside distinction is valid at several levels of the hierarchy. Rule: "You shouldn't have to open up a black box and take it apart to find out you've been pushing the wrong buttons!" Corollary: "Every black box should have at least TWO blinking lights: "Paper Jam" and "Service Required" ( or equivalent )" -Steve Majewski (804-982-0831) <sdm7g@Virginia.EDU> -Univ. of Virginia Department of Molecular Physiology and Biological Physics Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA12934 (5.65b/3.10/CWI-Amsterdam); Fri, 10 Sep 1993 00:17:05 +0200 From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: python-list@cwi.nl Subject: diffs to compile under SCO ODT 2.0 Date: Thu, 9 Sep 93 15:15:52 PDT Message-Id: <9309091516.aa21796@hermix.markv.com> Here is a set of diffs for the following files that will allow PYTHON 0.9.9 to compile under SCO ODT 2.0. I have not included the Makefile diffs but can make them available if someone wants them.. The diffs are for the following files: ceval.c, posixmodule.c, socketmodule.c, timemodule.c I hope these can get put into the distribution... Thank you, Lance Ellinghouse lance@markv.com =================================================================== RCS file: /u/lance/CVS/python/src/ceval.c,v retrieving revision 1.1.1.1 diff -c -r1.1.1.1 ceval.c *** 1.1.1.1 1993/09/09 20:57:38 --- ceval.c 1993/09/09 22:02:40 *************** *** 92,98 **** static void fast_2_locals PROTO((frameobject *)); static int access_statement PROTO((object *, object *, frameobject *)); - /* Pointer to current frame, used to link new frames to */ static frameobject *current_frame; --- 92,97 ---- *************** *** 1652,1658 **** err_setval(error_type, error_value); } ! static void mergelocals() { locals_2_fast(current_frame, 1); --- 1651,1657 ---- err_setval(error_type, error_value); } ! void mergelocals() { locals_2_fast(current_frame, 1); =================================================================== RCS file: /u/lance/CVS/python/src/posixmodule.c,v retrieving revision 1.1.1.1 diff -c -r1.1.1.1 posixmodule.c *** 1.1.1.1 1993/09/09 20:57:35 --- posixmodule.c 1993/09/09 22:05:16 *************** *** 35,41 **** #include <dos.h> #endif ! #ifdef __sgi #define DO_PG #endif --- 35,41 ---- #include <dos.h> #endif ! #if defined(__sgi) || defined(M_UNIX) #define DO_PG #endif =================================================================== RCS file: /u/lance/CVS/python/src/socketmodule.c,v retrieving revision 1.1.1.1 diff -c -r1.1.1.1 socketmodule.c *** 1.1.1.1 1993/09/09 20:57:35 --- socketmodule.c 1993/09/09 22:05:46 *************** *** 78,84 **** --- 78,86 ---- #include <signal.h> #include <sys/socket.h> #include <netinet/in.h> + #ifndef M_UNIX #include <sys/un.h> + #endif #include <netdb.h> #ifdef i860 *************** *** 233,243 **** --- 235,247 ---- return ret; } + #ifndef M_UNIX case AF_UNIX: { struct sockaddr_un *a = (struct sockaddr_un *) addr; return newstringobject(a->sun_path); } + #endif /* More cases here... */ *************** *** 263,268 **** --- 267,273 ---- { switch (s->sock_family) { + #ifndef M_UNIX case AF_UNIX: { static struct sockaddr_un addr; *************** *** 280,285 **** --- 285,291 ---- *len_ret = len + sizeof addr.sun_family; return 1; } + #endif case AF_INET: { *************** *** 318,328 **** --- 324,336 ---- { switch (s->sock_family) { + #ifndef M_UNIX case AF_UNIX: { *len_ret = sizeof (struct sockaddr_un); return 1; } + #endif case AF_INET: { *************** *** 1060,1066 **** --- 1068,1076 ---- if (SocketError == NULL || dictinsert(d, "error", SocketError) != 0) fatal("can't define socket.error"); insint(d, "AF_INET", AF_INET); + #ifndef M_UNIX insint(d, "AF_UNIX", AF_UNIX); + #endif insint(d, "SOCK_STREAM", SOCK_STREAM); insint(d, "SOCK_DGRAM", SOCK_DGRAM); insint(d, "SOCK_RAW", SOCK_RAW); =================================================================== RCS file: /u/lance/CVS/python/src/timemodule.c,v retrieving revision 1.1.1.1 diff -c -r1.1.1.1 timemodule.c *** 1.1.1.1 1993/09/09 20:58:47 --- timemodule.c 1993/09/09 22:06:02 *************** *** 38,43 **** --- 38,47 ---- #include "myselect.h" /* Implies <sys/types.h>, <sys/time.h>, <sys/param.h> */ #endif + #ifdef M_UNIX + #define HAVE_GETTIMEOFDAY + #endif + #ifdef macintosh #define NO_UNISTD #endif *************** *** 70,75 **** --- 74,87 ---- #else /* !unix */ #include <time.h> #endif /* !unix */ + + #ifdef M_UNIX + #include <time.h> + #define _timezone timezone + #define _altzone altzone + #define _daylight daylight + #define _tzname tzname + #endif #ifdef SYSV /* Access timezone stuff */ Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA00616 (5.65b/3.10/CWI-Amsterdam); Fri, 10 Sep 1993 05:41:17 +0200 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id ab00891; 9 Sep 93 23:41 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA14343; Thu, 9 Sep 1993 23:40:59 -0400 Date: Thu, 9 Sep 1993 23:40:59 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199309100340.AA14343@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: python-list@cwi.nl Subject: Obfuscated Python Contest Entry #!/usr/local/bin/python # # Obfuscated Python Contest Entry # -or- # How to make your python look more like C. # # submitted without comment by: # Steve Majewski <sdm7g@Virginia.EDU> # from sys import stdin,stdout The_End = '_An_Expected_End_of_Input_' def err(s): raise s def getline(): return( stdin.readline() or err(The_End) ) def echo(): try: while( stdout.write(getline()) or 1 ) : pass except The_End: print The_End echo() Received: from hopscotch.ksr.com by charon.cwi.nl with SMTP id AA01622 (5.65b/3.10/CWI-Amsterdam); Fri, 10 Sep 1993 06:24:48 +0200 Received: from ksr.com (frankenstein.ksr.com) by hopscotch.ksr.com with SMTP id AA12305; Fri, 10 Sep 1993 00:22:10 -0400 Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA29996; Fri, 10 Sep 93 00:22:05 EDT Received: by kaos.ksr.com (4.1/KSR-2.0) id AA10199; Fri, 10 Sep 93 00:22:02 EDT Message-Id: <9309100422.AA10199@kaos.ksr.com> To: sdm7g@virginia.edu, python-list@cwi.nl Subject: Re: Thoughts and proposals about types and classes Date: Fri, 10 Sep 93 00:22:01 -0400 From: Tim Peters <tim@ksr.com> There's a footnote in the reference manual, to the effect that Python "should" distinguish among classes implementing sequences, mappings, and numerics. There it's in the context of explaining the strange coercion behavior for __add__ and __mul__ methods, but you're surely right that it could have broader use. The presence or absence of an __isnumeric__/ __issequence__/__ismapping__ attribute seems a decent way to make this distinction. I'm not sure what _meaning_ to ascribe to these predicates, though! E.g., you've found it convenient to define a sequence type (the buffered input class) that doesn't want to implement __getslice__ (for efficiency reasons), and I've found it convenient to define a numeric type (the Date class) that doesn't want to implement _most_ of the "numeric" operations. Similarly, I suspect we both implement one-shot (throwaway, whatever) sequence/mapping/numeric classes, purely for short-term syntactic convenience, that don't implement most of the sequence/mapping/numeric special methods. And, e.g., I suspect that nobody yet has implemented a new numeric type that supports the __lshift__ method -- not that it can't be useful to do so, but that it's bound to be useful only rarely for a new numeric type (what could it mean to shift a complex number? etc). So I worry that if isnumeric(thing), issequence(thing) (etc) are added to the language, we'll still be left wondering "OK, isequence(thing)/ isnumeric(thing)/whatever was true, but what _operations_ does this thing support?". If the answer is "it's up to the user to define-- and stick to --their own conventions on this", there's little reason to build it into the language, since the same effect can be easily-enough achieved "by hand", by building the knowledge into a common module. But if Python defines-- and enforces --some convention, we'll find it overly restrictive unless it's too weak to solve the problem. About using try/except to catch the kinds of errors in question, fully agreed it's a bad approach. When implementing new types that are misused, the "in the bowels" exceptions are as often attribute errors as type errors. Sticking both kinds of exceptions on an enclosing "try" is just begging for trouble. > But if python actively discourages error checking by making it awkward > or difficult or time consuming, then its use for more ambitious "end > user" programs may be limited. Well, even now it's less awkward in Python than in, e.g., COBOL, BASIC, C or Fortran, but the latter get used anyway for far too many end user programs that are far too ambitious <grin>. I'm not convinced Python _can_ supply a solution to this, but it would help if building one's own solution were a little cleaner. E.g., a short way to spell "type(THING) is type(a_class_instance) and THING.__class__ is CLASS" (or "... and (THING.__class__ is CLASS or CLASS in THING.__class__.__bases__") would save a fair amount of discouraging tedium. > ... > Especially in the light of my pedantic (actual) complaint that > array.read( file, count ) OUGHT to be array.readfrom( file, count ) > since there should be a reasonable expectation that obj.read() is a > method of something that can be "read" and takes an argument of "how > much". Your objection made good sense to me! > ... > I don't think 'seq[int]' is an unreasonable restriction. But I do <grin>. Note that, unlike __getslice__, __getitem__ can get passed absolutely anything (ints, regexps, modules, lists, functions, files, ...). I have code that depends on that <wink>. and-my-own-code-is-the-measure-of-all-things-ly y'rs - tim Tim Peters tim@ksr.com not speaking for Kendall Square Research Corp Received: from hopscotch.ksr.com by charon.cwi.nl with SMTP id AA01762 (5.65b/3.10/CWI-Amsterdam); Fri, 10 Sep 1993 06:31:06 +0200 Received: from ksr.com (frankenstein.ksr.com) by hopscotch.ksr.com with SMTP id AA12321; Fri, 10 Sep 1993 00:28:20 -0400 Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA00114; Fri, 10 Sep 93 00:28:16 EDT Received: by kaos.ksr.com (4.1/KSR-2.0) id AA10338; Fri, 10 Sep 93 00:28:13 EDT Message-Id: <9309100428.AA10338@kaos.ksr.com> To: sdm7g@virginia.edu Subject: Re: Obfuscated Python Contest Entry Cc: python-list@cwi.nl Date: Fri, 10 Sep 93 00:28:12 -0400 From: Tim Peters <tim@ksr.com> That's disgusting! In a recent internal memo, I noted that "an obfuscated Python constest is darned-near unimaginable". Thanks for making a liar out of me <wink>. usually-able-to-manage-that-task-all-by-myself-ly y'rs - tim Received: from schelvis.cwi.nl by charon.cwi.nl with SMTP id AA09010 (5.65b/3.10/CWI-Amsterdam); Fri, 10 Sep 1993 11:16:46 +0200 Received: by schelvis.cwi.nl with SMTP id AA01623 (5.65b/3.8/CWI-Amsterdam); Fri, 10 Sep 1993 11:16:45 +0200 Message-Id: <9309100916.AA01623=jack@schelvis.cwi.nl> To: python-list@cwi.nl Subject: Re: Thoughts and proposals about types and classes In-Reply-To: Message by Tim Peters <tim@ksr.com> , Fri, 10 Sep 93 00:22:01 -0400 , <9309100422.AA10199@kaos.ksr.com> Organisation: Multi-media group, CWI, Kruislaan 413, Amsterdam Phone: +31 20 5924098(work), +31 20 5924199 (fax), +31 20 6160335(home) X-Last-Band-Seen: Kliek, Lyres (Sleepin, 2-9) X-Mini-Review: Groovy sixties, man.... Date: Fri, 10 Sep 1993 11:16:45 +0200 From: Jack Jansen <Jack.Jansen@cwi.nl> I have been thinking along the lines of something where you could ask python 'would it be ok if I tried to do <this> with <that>?', which is often what you use type() for. An example: def oldstyle(x): if type(x) in (type(()), type([])): for i in range(len(x)): print i, x[i] else: print x def newstyle(x): if allowed(x[0]): for i in range(len(x)): print i, x[i] else: print x This allowed() builtin would also obviate the need for the horrible 'type(x) in (type(0), type(0L), type(0.0), etc)' constructs, by allowing you to ask 'allowed(x+1)'. There's a potential implementation problem with allowed(), though, depending on how syntax analysis/execution work. Hmpf, where is Guido when you need him... -- Jack Jansen | If I can't dance I don't want to be part of Jack.Jansen@cwi.nl | your revolution -- Emma Goldman uunet!cwi.nl!jack G=Jack;S=Jansen;O=cwi;PRMD=surf;ADMD=400net;C=nl Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA02430 (5.65b/3.10/CWI-Amsterdam); Fri, 10 Sep 1993 22:11:18 +0200 Received: from [138.95.9.34] by gateway.sequent.com (5.61/1.34) id AA04522; Fri, 10 Sep 93 13:12:21 -0700 Received: from ushqgw1.sequent.com by relay1.sequent.com (5.65/crg/11) id AA26421; Fri, 10 Sep 93 12:08:08 -0700 Received: by ushqgw.sequent.com with Microsoft Mail id <2C90CF31@ushqgw.sequent.com>; Fri, 10 Sep 93 12:02:09 PDT From: "Jaap Vermeulen (jaap)" <jaap@sequent.com> To: jack <jack@cwi.nl>, python-list <python-list@cwi.nl> Subject: Re: Thoughts and proposals about types and classes Date: Fri, 10 Sep 93 09:48:00 PDT Message-Id: <2C90CF31@ushqgw.sequent.com> Encoding: 37 TEXT X-Mailer: Microsoft Mail V3.0 | def oldstyle(x): | if type(x) in (type(()), type([])): | for i in range(len(x)): | print i, x[i] | else: | print x What about: def altstyle(x) try: for i in range(len(x)): print i, x[i] except TypeError: print x Here you would rely on the fact that len(x) would return TypeError on an unsized object. Or, the x[i] would return TypeError on an unsubscriptable object. Either way, if Python would move towards a more pure OO paradigm, the subscription would become a method and you should be able the turn the allowed() into a simple check whether a method exists. This brings to another point from the previous discussion with Steven. In most cases when you decide to forego on the type checking, you will run into either a TypeError or an AttributeError if the wrong object was passed in (as Jack points out). In a more pure OO environment with a perfect namespace, you would refer to a method that doesn't exist for that object (given the wrong object was passed in). Disclaimer: With a "pure OO paradigm" I refer to an environment solely based on method lookup. -Jaap- Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA28767 (5.65b/3.10/CWI-Amsterdam); Fri, 10 Sep 1993 20:48:33 +0200 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa21372; 10 Sep 93 14:48 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA17439; Fri, 10 Sep 1993 14:48:24 -0400 Date: Fri, 10 Sep 1993 14:48:24 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199309101848.AA17439@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: Jack Jansen <Jack.Jansen@cwi.nl>, python-list@cwi.nl Subject: Re: Thoughts and proposals about types and classes On Sep 10, 11:16, Jack Jansen wrote: > > I have been thinking along the lines of something where you could ask > python 'would it be ok if I tried to do <this> with <that>?', which is > often what you use type() for. > [ ... ] > > This allowed() builtin would also obviate the need for the horrible > 'type(x) in (type(0), type(0L), type(0.0), etc)' constructs, by > allowing you to ask 'allowed(x+1)'. > Well - there is 'hasattr()', so for user classes you can check for hasattr( thing, '__add__' ). The builtins types have to be a special case test. But contrary to my expectation, hasattr( 1, '__add__' ) didn't raise an exception and complain about not being a class or instance - it just returned NO: >>> hasattr( 1, '__add__' ) hasattr( 1, '__add__' ) 0 >>> But your syntax would HAVE to be a builtin operator to keep allowed( x + 1 ) from evaluating "x + 1" first. I assume this is the problem you are refering to below. But the real problem is the one Tim brought up - if may be "allowed" , but what does it _mean_, and how can you tell until you try it? You want to know: (1) if "x" is either a builtin type that supports "+" or hasattr( x, '__add__' ); (2) can type x coerce '1' into the necessary type ? ; AND (3) does 'x + 1' REALLY MEAN what I think it does?. I thought I was getting around that by stating that "isnumeric(x) == True" means that the implementor of it's class has PROMISED that "x + 1" does, in fact, mean something reasonable. I now have some doubts that it can do all that I had hoped. :-( > There's a potential implementation problem with allowed(), though, > depending on how syntax analysis/execution work. Hmpf, where is Guido > when you need him... According to his vacation message, I think he is somewhere in the USA right now. Guido - If you had only told us in advance, we would have organized a fan-club meeting! - Steve M. Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA05842 (5.65b/3.10/CWI-Amsterdam); Mon, 13 Sep 1993 19:12:59 +0200 Received: by hermix.markv.com id ad15762; 13 Sep 93 10:10 PDT From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: python-list@cwi.nl Mmdf-Warning: Unable to confirm address in preceding line at hermix.markv.com Subject: question about exec() and compile() Date: Sun, 12 Sep 93 16:02:53 PDT Message-Id: <9309121603.aa11689@hermix.markv.com> I have a file that looks like this: t = 1 def Test(): print 't = ' + `t` def test2(): print 'calling Test()' Test() I read in the file and want to execute test2(). So I do the following: f = open('file','r') a = f.read() f.close() a_c = compile(a,'<string>','exec') local_ns = {} global_ns = {} exec(a_c,global_ns,local_ns) Now if I dump local_ns, it shows 't', 'Test' and 'test2' as being members of local_ns. global_ns is still empty. Now how can I call test2? I have tried local_ns['test2']() but it says it cannot find 'Test' I CANNOT use 'import' as this code is actually part of a file that cannot be run.. Any ideas????? Thanks! Lance Ellinghouse lance@markv.com Received: from hopscotch.ksr.com by charon.cwi.nl with SMTP id AA11787 (5.65b/3.10/CWI-Amsterdam); Mon, 13 Sep 1993 05:54:32 +0200 Received: from ksr.com (frankenstein.ksr.com) by hopscotch.ksr.com with SMTP id AA23064; Sun, 12 Sep 1993 23:51:32 -0400 Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA27612; Sun, 12 Sep 93 23:51:20 EDT Received: by kaos.ksr.com (4.1/KSR-2.0) id AA21576; Sun, 12 Sep 93 23:51:00 EDT Message-Id: <9309130351.AA21576@kaos.ksr.com> To: Jack.Jansen@cwi.nl, sdm7g@virginia.edu, jaap@sequent.com Subject: Re: Thoughts and proposals about types and classes Cc: python-list@cwi.nl Date: Sun, 12 Sep 93 23:50:59 -0400 From: Tim Peters <tim@ksr.com> > [jack] > def oldstyle(x): > if type(x) in (type(()), type([])): > for i in range(len(x)): > print i, x[i] > else: > print x > > def newstyle(x): > if allowed(x[0]): > for i in range(len(x)): > print i, x[i] > else: > print x Is if allowed(expression): block1 else: block2 different from (assuming 'ok' and 'dummy' are otherwise unused) ok = 1 try: dummy = expression except (TypeError, AttributeError): ok = 0 if ok: block1 else: block2 ? I suppose you don't actually want to evaluate 'expression', though, or more likely specifically want _not_ to evaluate 'expression'. I'm not sure that's possible in general, though. For example, even if x is an instance of a class that supports a __sub__ method, there's no guarantee that, e.g., x-1 will end up invoking x.__sub__: it depends on what x.__coerce__ decides to do, and I doubt that's determinable, in general, without executing the code. I like the _idea_, because it gets directly at Guido's pragmatic "does the object support the operation or not?" test. I'm just dubious that it can be made to work unless the argument is restricted to operations on built-in objects (about whose behavior Python knows everything up front). > [steve] > >>> hasattr( 1, '__add__' ) > >>> 0 Cute! Makes sense, though, eh? Here's another one to ponder: >>> class K: ... def __len__(self): ... return 12 ... >>> temp=K(); hasattr(temp,'__len__'); len(temp) 1 12 >>> temp=K; hasattr(temp,'__len__'); len(temp) 1 Stack backtrace (innermost last): File "<stdin>", line 1 TypeError: len() of unsized object >>> I.e., just because something has a __len__ attribute doesn't necessarily mean you can apply the len function to it. Presumably Jack's 'allowed(len(K))' would have returned 0 here. > [jaap] > def altstyle(x) > try: > for i in range(len(x)): > print i, x[i] > except TypeError: > print x I'm not clear on what Jack intended in the original example. "oldstyle" did the "for i in range ..." bit for and only for tuples and lists. "newstyle" did it (I think) for and only for tuples, lists, and objects that support __getitem__. However, it would raise an exception for objects that did support __getitem__ but not __len__. In any case, it doesn't do the same thing as "oldstyle" in all cases. The code of which I asked "does this differ from oldstyle?" has somewhat different behavior from both of those, and from "altstyle". altstyle hides what might be legitimate runtime type errors in an object's __len__ or __getitem__ method, and raises AttributeError for objects that don't support __len__, or that do support a __len__ that returns a value > 0 but don't support __getitem__. I don't mean to be irritatingly pedantic there <grin>; the primary real point is that I think the problem we're trying to _solve_ with this stuff is remarkably ill-defined (else at least _some_ pair of proposed solutions would get close to having the same behavior <wink>). > Here you would rely on the fact that len(x) would return TypeError on an > unsized object. Or, the x[i] would return TypeError on an unsubscriptable > object. Just noting that the absence of __getitem__ yields AttributeError instead of TypeError. > Either way, if Python would move towards a more pure OO paradigm, the > subscription would become a method and you should be able the turn the > allowed() into a simple check whether a method exists. See the "class K" example above for a context where this doesn't work as hoped. Is that the only exception? Suspect it is. instinctively-suspicious-of-"pure"-anything<wink>-ly y'rs - tim Tim Peters tim@ksr.com not speaking for Kendall Square Research Corp Received: from schelvis.cwi.nl by charon.cwi.nl with SMTP id AA20337 (5.65b/3.10/CWI-Amsterdam); Mon, 13 Sep 1993 11:51:10 +0200 Received: by schelvis.cwi.nl with SMTP id AA07253 (5.65b/3.8/CWI-Amsterdam); Mon, 13 Sep 1993 11:51:09 +0200 Message-Id: <9309130951.AA07253=jack@schelvis.cwi.nl> To: python-list@cwi.nl Subject: Re: Thoughts and proposals about types and classes In-Reply-To: Message by Tim Peters <tim@ksr.com> , Sun, 12 Sep 93 23:50:59 -0400 , <9309130351.AA21576@kaos.ksr.com> Organisation: Multi-media group, CWI, Kruislaan 413, Amsterdam Phone: +31 20 5924098(work), +31 20 5924199 (fax), +31 20 6160335(home) X-Last-Band-Seen: Maroon Town (Melkweg, 4-9) X-Mini-Review: Ska with a little jazz, soul, raggamixed in for good measure. Date: Mon, 13 Sep 1993 11:51:08 +0200 From: Jack Jansen <Jack.Jansen@cwi.nl> The point of my original example was indeed that the allowed() expression was *not* evaluated, so that possible side-effects are no problem. Otherwise the try/except construct woudl be good enough (except for the fact that it doesn't really lead to well-structured code in all cases). There's a serious flaw in the whole idea, though, that was pointed out by Dik Winter: the semantics are unclear. If I say "allowed(x+1)" it is clear enough (even though there are implementation difficulties, as Tim pointed out): check wether x has an add method that supports integer arguments. If I say "allowed(foo())" ditto, I think: check that foo is a function. If I say "allowed(foo()+1)" it becomes undecidable without calling foo, since foo might return a different type depending on the phase of the moon. Even a restriction that you may use only one operator within the allowed() expression is not good enough: you really want to be able to say "allowed(len(x))", but here we're already testing two things: besides testing wether x has a length (which is probably what we want to test) we also test that len is a function. Moreover, we actually use the semantics of len for the test we are really interested in, and I can't see an easy way of doing that without executing len. Oh well, another interesting idea down the drain, -- Jack Jansen | If I can't dance I don't want to be part of Jack.Jansen@cwi.nl | your revolution -- Emma Goldman uunet!cwi.nl!jack G=Jack;S=Jansen;O=cwi;PRMD=surf;ADMD=400net;C=nl Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA28336 (5.65b/3.10/CWI-Amsterdam); Mon, 13 Sep 1993 15:38:42 +0200 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa13137; 13 Sep 93 9:38 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA15048; Mon, 13 Sep 1993 09:38:27 -0400 Date: Mon, 13 Sep 1993 09:38:27 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199309131338.AA15048@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: Jack Jansen <Jack.Jansen@cwi.nl>, python-list@cwi.nl Subject: Re: Thoughts and proposals about types and classes On Sep 13, 11:51, Jack Jansen wrote: > > There's a serious flaw in the whole idea, though, that was pointed out > by Dik Winter: the semantics are unclear. If I say "allowed(x+1)" it > is clear enough (even though there are implementation difficulties, as > Tim pointed out): check wether x has an add method that supports > integer arguments. If I say "allowed(foo())" ditto, I think: check that > foo is a function. If I say "allowed(foo()+1)" it becomes undecidable > without calling foo, since foo might return a different type depending > on the phase of the moon. > I think what you have stumbled across here, Jack, is the probability that the sort of feature we've been talking about may only be able to be implemented ( of if implemented, used ) in a limited fashion in a dynamic/loosely typed O-O language. It might actually work in a compiled, strongly-typed, type-inference class based type language, where allowed( foo()+1 ) would most often turn into a compile time consistency check, and only turn into a runtime test when there was not enough context to determine what set of objects 'foo' could possibly be bound to. > > Oh well, another interesting idea down the drain, This is the 2nd time I've tried to recall a Cardelli paper about the addition of type 'Dynamic' to Modula-3 : the question came up in another forum about how much checking was done at compile time and how much at run time. ( Dynamic was an attempt to add a dynamic run time typing to a language that was strongly compile time typed in a SAFE manner - i.e. without breaking all of the type checking with the contagion of uncertainty. ) I know Guido has stated that Modula-3 was one of the inspirations for python - perhaps he will have some comment when he get back. - Steve M. Received: from hydra.acs.uci.edu by charon.cwi.nl with SMTP id AA02316 (5.65b/3.10/CWI-Amsterdam); Mon, 13 Sep 1993 17:25:10 +0200 Received: from localhost by hydra.acs.uci.edu with SMTP id AA07568 (5.65c/IDA-1.4.4 for <python-list@cwi.nl>); Mon, 13 Sep 1993 08:24:57 -0700 Message-Id: <199309131524.AA07568@hydra.acs.uci.edu> To: Tim Peters <tim@ksr.com> Cc: python-list@cwi.nl Subject: Re: Thoughts and proposals about types and classes In-Reply-To: Your message of "Sun, 12 Sep 93 23:50:59 EDT." <9309130351.AA21576@kaos.ksr.com> Date: Mon, 13 Sep 93 08:24:54 -0700 From: Dan Stromberg - OAC-DCS <strombrg@hydra.acs.uci.edu> It would seem one way of determining if a failure to execute a method with a specific type is: 1) due to the lack of that method presence at all or 2) due to the lack of an appropriate coercion ...would be to provide one or two constants with each numeric type. "zero" and "one" would be good candidates, "one" alone being more useful than "zero" alone. Of course, that means adding a constant or two to a fair number of types, but... Given the presence of a constant "one", and operators for addition and multiplication, it would probably be possible to provide a fairly efficient, inheritable routine for converting ascii to a new numeric type... In message <9309130351.AA21576@kaos.ksr.com> you write: >> [jack] >> def oldstyle(x): >> if type(x) in (type(()), type([])): >> for i in range(len(x)): >> print i, x[i] >> else: >> print x >> >> def newstyle(x): >> if allowed(x[0]): >> for i in range(len(x)): >> print i, x[i] >> else: >> print x > >Is > > if allowed(expression): > block1 > else: > block2 > >different from (assuming 'ok' and 'dummy' are otherwise unused) > > ok = 1 > try: > dummy = expression > except (TypeError, AttributeError): > ok = 0 > > if ok: > block1 > else: > block2 > >? I suppose you don't actually want to evaluate 'expression', though, or >more likely specifically want _not_ to evaluate 'expression'. I'm not >sure that's possible in general, though. For example, even if x is an >instance of a class that supports a __sub__ method, there's no guarantee >that, e.g., > > x-1 > >will end up invoking x.__sub__: it depends on what x.__coerce__ decides >to do, and I doubt that's determinable, in general, without executing the >code. > >I like the _idea_, because it gets directly at Guido's pragmatic "does >the object support the operation or not?" test. I'm just dubious that it >can be made to work unless the argument is restricted to operations on >built-in objects (about whose behavior Python knows everything up front). > >> [steve] >> >>> hasattr( 1, '__add__' ) >> >>> 0 > >Cute! Makes sense, though, eh? > >Here's another one to ponder: > >>>> class K: >... def __len__(self): >... return 12 >... >>>> temp=K(); hasattr(temp,'__len__'); len(temp) >1 >12 >>>> temp=K; hasattr(temp,'__len__'); len(temp) >1 >Stack backtrace (innermost last): > File "<stdin>", line 1 >TypeError: len() of unsized object >>>> > >I.e., just because something has a __len__ attribute doesn't necessarily >mean you can apply the len function to it. Presumably Jack's >'allowed(len(K))' would have returned 0 here. > >> [jaap] >> def altstyle(x) >> try: >> for i in range(len(x)): >> print i, x[i] >> except TypeError: >> print x > >I'm not clear on what Jack intended in the original example. > >"oldstyle" did the "for i in range ..." bit for and only for tuples and >lists. > >"newstyle" did it (I think) for and only for tuples, lists, and objects >that support __getitem__. However, it would raise an exception for >objects that did support __getitem__ but not __len__. In any case, it >doesn't do the same thing as "oldstyle" in all cases. > >The code of which I asked "does this differ from oldstyle?" has somewhat >different behavior from both of those, and from "altstyle". altstyle >hides what might be legitimate runtime type errors in an object's __len__ >or __getitem__ method, and raises AttributeError for objects that don't >support __len__, or that do support a __len__ that returns a value > 0 >but don't support __getitem__. > > >I don't mean to be irritatingly pedantic there <grin>; the primary real >point is that I think the problem we're trying to _solve_ with this stuff >is remarkably ill-defined (else at least _some_ pair of proposed >solutions would get close to having the same behavior <wink>). > > >> Here you would rely on the fact that len(x) would return TypeError on an >> unsized object. Or, the x[i] would return TypeError on an unsubscriptable >> object. > >Just noting that the absence of __getitem__ yields AttributeError instead >of TypeError. > >> Either way, if Python would move towards a more pure OO paradigm, the >> subscription would become a method and you should be able the turn the >> allowed() into a simple check whether a method exists. > >See the "class K" example above for a context where this doesn't work as >hoped. Is that the only exception? Suspect it is. > >instinctively-suspicious-of-"pure"-anything<wink>-ly y'rs - tim > >Tim Peters tim@ksr.com >not speaking for Kendall Square Research Corp Dan Stromberg - OAC/DCS strombrg@uci.edu Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA06586 (5.65b/3.10/CWI-Amsterdam); Mon, 13 Sep 1993 19:30:47 +0200 To: lance@markv.com Cc: python-list@cwi.nl In-Reply-To: <9309121603.aa11689@hermix.markv.com> (message from Lance Ellinghouse on Sun, 12 Sep 93 16:02:53 PDT) Subject: Re: question about exec() and compile() X-Organization: Mark V Systems Ltd. X-Address: 16400 Ventura Blvd Suite 303, Encino, Ca, 91436, USA X-Phone: +1 818 995 7671 (work), +1 818 995 4267 (fax) Date: Mon, 13 Sep 93 10:29:22 PDT From: lance@markv.com Sender: lance@markv.com Message-Id: <9309131029.aa17663@hermix.markv.com> Source-Info: From (or Sender) name not authenticated. I figured out a hack to allow me to do what I want.... I just have to add 1 line of code as shown below.. > I have a file that looks like this: > t = 1 > > def Test(): > print 't = ' + `t` > > def test2(): > print 'calling Test()' > Test() > > > I read in the file and want to execute test2(). > > So I do the following: > > f = open('file','r') > a = f.read() > f.close() > a_c = compile(a,'<string>','exec') > local_ns = {} > global_ns = {} > exec(a_c,global_ns,local_ns) exec(a_c,local_ns,local_ns) now I can say: local_ns['test2']() and the result will be calling Test() t = 1 This is what I wanted to be able to do.. Sorry for wasting net-bandwidth on this.. -- Lance Ellinghouse lance@markv.com 1231 bit key fingerprint = 56 DA 31 0C 17 51 36 6A 4E D4 E0 11 D9 B8 06 0A 1024 bit key fingerprint = 66 2C 75 F2 E9 1C 32 84 3A E3 B0 5E 48 01 4C 37 You can receive my Public Key by `finger lance@mark.com` Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA09030 (5.65b/3.10/CWI-Amsterdam); Mon, 13 Sep 1993 20:23:27 +0200 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa02171; 13 Sep 93 14:23 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA13074; Mon, 13 Sep 1993 14:23:19 -0400 Date: Mon, 13 Sep 1993 14:23:19 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199309131823.AA13074@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: python-list@cwi.nl Subject: My other pet python peeve - .sort(),.reverse(), etc. return None Although I'm generally a python fan and booster, there are a couple of quirks in the language that I sometimes find frustrating. ( Tim and I were discussing a few of them, offline, in a thread started by my 'obfuscated python' post. ) Some of them may be unavoidable features of other aspects of python's syntax and/or model of execution. But one that often catches me, because it seems (to me) rather arbitrary is the fact the some of the list methods, like .sort, .reverse, .append, all return None. I would think it preferable to return the new list. Why? [ I know I may have to await Guido's return to get an authoritive answer. ] The only reason that comes to mind, is that that design feature was intended as a reminder that those methods are not, strictly speaking, _functions_, but _procedures_ that produce side effects: "whatch out! - x.sort() is going to change the value of x - not just return a NEW sequence!" ) To a C and/or Lisp programmer, who is used to the idea that everything is a function - some are not PURE side-effect-less functions, and some don't return anything useful, but they are all functions, this does not seem a very intuitive distinction. ( Maybe it *does( if you are comming from Modula-[23]. I don't know. ) What's more: there is nothing to stop you from SAYING: [ 1,2,3,4 ].sort() [ 1,2,3,4 ].append( 5 ) [ 1,2,3,4 ].reverse() all of which, of course, return None, NOT the result of applying method to the anonymous sequence. ( An exception would seem to be called for here, although, I don't expect that .sort() has any way in hell of KNOWING that it is being called on an anonymous list. ) So I can't say, for example: string.split( file.readline() ).sort() [ In practice, lack of append() returning a value isn't usually a problem: the expression is typically part of a 'return' or an assignment, so, for example: "return string.join( list ) + '\n'" is the typical idiom. ] I know this isn't Guido's style. But it's *MY* style, and I'm fond of it, ( as you can probably tell from my 'obfuscated python' ;-) and it *seems* (IMHO) to be a rather _arbitrary_ restriction. ( And I can't even think of some likely + reasonable code that would be broken by the change. I can't think that anyone ever *tests* that "list.sort() == None" - since that is, in fact, the only possible return value. ) -Steve Majewski (804-982-0831) <sdm7g@Virginia.EDU> -Univ. of Virginia Department of Molecular Physiology and Biological Physics Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA19555 (5.65b/3.10/CWI-Amsterdam); Tue, 14 Sep 1993 01:37:27 +0200 To: python-list@cwi.nl Subject: purify report from testall run X-Signed: PGP-Attached-clearsig-2-3, iQCVAgUBLJUD12nDnXuZ0ONVAQF7KwP/T07qUgZj4CfbZaGvPmRLOiJuzxP5vRb5 up+PAPH4MCU/GUFu3hnSEyP3VFThLDD2Cv3ooK8VKCz4peIxOrvyMGUQ7wpOyFoW dWlVNkt1KU+2W2C3THBmAamA3Yq5Nz42MCz3BGhIOXRKPbRa/q7mNu4ikFDsPFCy D64bVHg5/iE= X-Organization: Mark V Systems Ltd. X-Address: 16400 Ventura Blvd Suite 303, Encino, Ca, 91436, USA X-Phone: +1 818 995 7671 (work), +1 818 995 4267 (fax) Date: Mon, 13 Sep 93 16:36:15 PDT From: lance@markv.com Sender: lance@markv.com Message-Id: <9309131636.aa10022@hermix.markv.com> Source-Info: From (or Sender) name not authenticated. I was curious about memory usage in Python... I compiled python for purify and ran 'testall' to give it a good test.. here is the pyrify report.. Purify'd python (pid 19353) Purify 2 (C) 1990-93 Pure Software Inc. Patents Pending. Contact us at: support@pure.com or (408) 720 1600. In Europe: support@pts.co.uk or (+44) 61 776 4499. Purify checking enabled. **** Purify'd python (pid 19353) **** Purify (umr): uninitialized memory read: * This is occurring while in: initstrop [line 385, stropmodule.c, pc=0x46b1c] init_builtin [line 403, import.c, pc=0x753fc] import_module [line 341, import.c, pc=0x74ee4] eval_code [line 1202, ceval.c, pc=0x526c0] get_module [line 317, import.c, pc=0x74cb8] load_module [line 327, import.c, pc=0x74da8] * Reading 4 bytes from 0xf7ffd994 on the stack This is local variable "s" in function initstrop. >>> Purify: Searching for all memory leaks... There are 3967 leaked bytes (7.98% of the 49683 allocated bytes in the heap) 28 bytes (2 times) + 27 + 26 (4 times) + 24 (9 times) + 23 (8 times) + 22 (7 times) + 21 (14 times) + 20 (6 times) + 18 (16 times) + 17 (3 times). Last memory leak at 0x2324e0 Report (mlk): 1494 total bytes lost, malloc called from: newstringobject [line 52, stringobject.c, pc=0x3541c] compile [line 2278, compile.c, pc=0x6cbb4] com_funcdef [line 1774, compile.c, pc=0x6a434] com_node [line 1845, compile.c, pc=0x6ac88] com_node [line 1871, compile.c, pc=0x6ae20] com_node [line 1856, compile.c, pc=0x6ace4] 16 bytes + 15 (8 times) + 14 (8 times) + 13 (15 times) + 12 (11 times) + 11 Last memory leak at 0x141258 Report (mlk): 586 total bytes lost, malloc called from: initmodule [line 45, modsupport.c, pc=0x23b18] initposix [line 1232, posixmodule.c, pc=0x2ba38] init_builtin [line 403, import.c, pc=0x753fc] import_module [line 341, import.c, pc=0x74ee4] eval_code [line 1202, ceval.c, pc=0x526c0] eval_node [line 323, pythonrun.c, pc=0x2e1a0] 19 bytes + 18 (2 times) + 17 (4 times) + 16 (3 times) + 15 (5 times) + 14 (7 times) + 13 (13 times) + 12 Last memory leak at 0x1379d0 Report (mlk): 525 total bytes lost, malloc called from: initmodule [line 45, modsupport.c, pc=0x23b18] initbuiltin [line 890, bltinmodule.c, pc=0x4d7c4] initall [line 77, pythonrun.c, pc=0x2cca4] main [line 133, pythonmain.c, pc=0x1a380] start [crt0.o, pc=0x2064] 27 bytes + 26 (2 times) + 24 + 22 + 21 (8 times) + 20 (3 times). Last memory leak at 0x1c26e0 Report (mlk): 353 total bytes lost, malloc called from: __gnu_compiled_c [line 34, stringobject.c, pc=0x352f0] r_object [line 334, marshal.c, pc=0x212fc] r_object [line 385, marshal.c, pc=0x218b0] r_object [line 360, marshal.c, pc=0x215b4] r_object [line 382, marshal.c, pc=0x21850] rd_object [line 422, marshal.c, pc=0x21d00] 12 bytes (5 times) + 11 (11 times) + 10 (6 times). Last memory leak at 0x159e40 Report (mlk): 241 total bytes lost, malloc called from: initmodule [line 45, modsupport.c, pc=0x23b18] initmath [line 221, mathmodule.c, pc=0x23718] init_builtin [line 403, import.c, pc=0x753fc] import_module [line 341, import.c, pc=0x74ee4] eval_code [line 1202, ceval.c, pc=0x526c0] get_module [line 317, import.c, pc=0x74cb8] 22 bytes (3 times) + 21 (5 times) + 20 (2 times) + 19 Last memory leak at 0x13b508 Report (mlk): 230 total bytes lost, malloc called from: newstringobject [line 52, stringobject.c, pc=0x3541c] list_builtin_module_names [line 165, sysmodule.c, pc=0x3afc4] initsys [line 195, sysmodule.c, pc=0x3b428] initall [line 78, pythonrun.c, pc=0x2ccac] main [line 133, pythonmain.c, pc=0x1a380] start [crt0.o, pc=0x2064] 17 bytes (2 times) + 16 + 14 + 13 (2 times) + 12 (2 times) + 11 Last memory leak at 0x1437c0 Report (mlk): 125 total bytes lost, malloc called from: initmodule [line 45, modsupport.c, pc=0x23b18] inittime [line 365, timemodule.c, pc=0x3cb7c] init_builtin [line 403, import.c, pc=0x753fc] import_module [line 341, import.c, pc=0x74ee4] eval_code [line 1202, ceval.c, pc=0x526c0] get_module [line 317, import.c, pc=0x74cb8] 19 bytes + 18 + 16 + 13 (5 times). Last memory leak at 0x1fc230 Report (mlk): 118 total bytes lost, malloc called from: initmodule [line 45, modsupport.c, pc=0x23b18] initstrop [line 376, stropmodule.c, pc=0x46a2c] init_builtin [line 403, import.c, pc=0x753fc] import_module [line 341, import.c, pc=0x74ee4] eval_code [line 1202, ceval.c, pc=0x526c0] get_module [line 317, import.c, pc=0x74cb8] 18 bytes (2 times) + 17 (4 times). Last memory leak at 0x222e48 Report (mlk): 104 total bytes lost, malloc called from: newstringobject [line 52, stringobject.c, pc=0x3541c] compile [line 2278, compile.c, pc=0x6cbb4] com_classdef [line 1821, compile.c, pc=0x6a930] com_node [line 1848, compile.c, pc=0x6acb0] com_node [line 1871, compile.c, pc=0x6ae20] com_node [line 1856, compile.c, pc=0x6ace4] Report (mlk): 53 bytes at 0x13bab0 lost, malloc called from: realloc [p5.o, pc=0x4a24] ins1 [line 133, listobject.c, pc=0x7f74c] addlistitem [line 173, listobject.c, pc=0x7fb40] list_builtin_module_names [line 168, sysmodule.c, pc=0x3b000] initsys [line 195, sysmodule.c, pc=0x3b428] initall [line 78, pythonrun.c, pc=0x2ccac] 16 bytes + 14 + 10 Last memory leak at 0x13a800 Report (mlk): 40 total bytes lost, malloc called from: initmodule [line 45, modsupport.c, pc=0x23b18] initsys [line 180, sysmodule.c, pc=0x3b1f0] initall [line 78, pythonrun.c, pc=0x2ccac] main [line 133, pythonmain.c, pc=0x1a380] start [crt0.o, pc=0x2064] 19 bytes (2 times). Last memory leak at 0x1408b8 Report (mlk): 38 total bytes lost, malloc called from: __gnu_compiled_c [line 34, stringobject.c, pc=0x352f0] do_mkvalue [line 489, modsupport.c, pc=0x26330] do_mktuple [line 422, modsupport.c, pc=0x257f8] do_mkvalue [line 448, modsupport.c, pc=0x25d1c] vmkvalue [line 556, modsupport.c, pc=0x26690] mkvalue [line 537, modsupport.c, pc=0x26568] Report (mlk): 24 bytes at 0x140860 lost, malloc called from: newtupleobject [line 39, tupleobject.c, pc=0x3cff0] do_mktuple [line 419, modsupport.c, pc=0x25788] do_mkvalue [line 448, modsupport.c, pc=0x25d1c] vmkvalue [line 556, modsupport.c, pc=0x26690] mkvalue [line 537, modsupport.c, pc=0x26568] inittime [line 394, timemodule.c, pc=0x3ce04] Report (mlk): 17 bytes at 0x1f60d8 lost, malloc called from: __gnu_compiled_c [line 34, stringobject.c, pc=0x352f0] r_object [line 334, marshal.c, pc=0x212fc] r_object [line 385, marshal.c, pc=0x218b0] rd_object [line 422, marshal.c, pc=0x21d00] get_module [line 232, import.c, pc=0x745c8] reload_module [line 364, import.c, pc=0x750e4] Report (mlk): 16 bytes at 0x13b168 lost, malloc called from: __gnu_compiled_c [line 47, listobject.c, pc=0x7eff4] list_builtin_module_names [line 160, sysmodule.c, pc=0x3af3c] initsys [line 195, sysmodule.c, pc=0x3b428] initall [line 78, pythonrun.c, pc=0x2ccac] main [line 133, pythonmain.c, pc=0x1a380] start [crt0.o, pc=0x2064] Report (mlk): 3 bytes at 0x2187c8 lost, malloc called from: parsetok [line 157, parsetok.c, pc=0x887cc] parsestring [line 56, parsetok.c, pc=0x87e50] parse_string [line 372, pythonrun.c, pc=0x2e47c] run_string [line 270, pythonrun.c, pc=0x2de1c] exec_eval [line 224, bltinmodule.c, pc=0x4a148] builtin_exec [line 240, bltinmodule.c, pc=0x4a200] Purify Heap Analysis (combining suppressed and unsuppressed chunks) Chunks Bytes Leaked 232 3967 Potentially Leaked 0 0 In-Use 270 45716 ---------------------------------------- Total Allocated 502 49683 **** Purify'd python (pid 19353) **** * 1 access error. * Basic memory usage: 983032 code 275936 data/bss 1425424 heap 3208 stack * Shared library memory usage: 696320 libc_pure_200.so.1.7 (shared code) 16384 libc_pure_200.so.1.7 (private data) 8192 libinternal_stubs.so.1.0 (shared code) 8192 libinternal_stubs.so.1.0 (private data) - -- Lance Ellinghouse lance@markv.com 1231 bit key fingerprint = 56 DA 31 0C 17 51 36 6A 4E D4 E0 11 D9 B8 06 0A 1024 bit key fingerprint = 66 2C 75 F2 E9 1C 32 84 3A E3 B0 5E 48 01 4C 37 You can receive my Public Key by `finger lance@mark.com` Received: from hopscotch.ksr.com by charon.cwi.nl with SMTP id AA23091 (5.65b/3.10/CWI-Amsterdam); Tue, 14 Sep 1993 05:06:21 +0200 Received: from ksr.com (frankenstein.ksr.com) by hopscotch.ksr.com with SMTP id AA08564; Mon, 13 Sep 1993 23:03:57 -0400 Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA23600; Mon, 13 Sep 93 23:03:41 EDT Received: by kaos.ksr.com (4.1/KSR-2.0) id AA28191; Mon, 13 Sep 93 23:01:53 EDT Message-Id: <9309140301.AA28191@kaos.ksr.com> To: sdm7g@virginia.edu, python-list@cwi.nl Subject: Re: My other pet python peeve - .sort(),.reverse(), etc. return None Date: Mon, 13 Sep 93 23:01:52 -0400 From: Tim Peters <tim@ksr.com> > [steve, noting that [].sort(), [].reverse(), ..., return None instead > of the modified object, making natural-enough constructs like > string.split( file.readline() ).sort() > surprising > ] > ... > ( And I can't even think of some likely + reasonable code that would > be broken by the change. ... For a reasonable counterexample, how about every program you have <0.1 grin>? That is, whenever you have thing.sort() now, it yields None, and _because_ it yields None specifically, Python doesn't print the value: >>> [1,2,3] # non-None result is printed [1, 2, 3] >>> None # None result is not printed >>> So if thing.sort() (or reverse or append) were to return the sorted (reversed, appended) object instead, every existing line like that would start producing output. Yeech! I suspect Jaap would disagree, but as a pragmatic matter I like Python's mix of functional, procedural, and OO flavors -- different bullets for different beasts. It's hard to judge which flavor is best for each built-in concept, though. Anyway, here's a cheap (& I dare say obvious <wink>) workaround I use. Haven't upgraded this since [].sort() grew its optional comparison- function argument, but that's clearly easy to add: def sort(thing): thing.sort() return thing Then, e.g., process(sort(string.split( file.readline() ))) works fine. I too dislike the temp = string.split( file.readline() ) temp.sort() process( temp ) alternative. non-decreasing-ly y'rs - tim Tim Peters tim@ksr.com not speaking for Kendall Square Research Corp Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA25037 (5.65b/3.10/CWI-Amsterdam); Tue, 14 Sep 1993 09:08:27 +0200 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa05094; 14 Sep 93 3:08 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA11742; Tue, 14 Sep 1993 03:08:18 -0400 Date: Tue, 14 Sep 1993 03:08:18 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199309140708.AA11742@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: Tim Peters <tim@ksr.com>, sdm7g@virginia.edu, python-list@cwi.nl Subject: Re: My other pet python peeve - .sort(),.reverse(), etc. return None On Sep 13, 23:01, Tim Peters wrote: > > ... > > ( And I can't even think of some likely + reasonable code that would > > be broken by the change. ... > > For a reasonable counterexample, how about every program you have <0.1 > grin>? That is, whenever you have > > thing.sort() > > now, it yields None, and _because_ it yields None specifically, Python > doesn't print the value: > > So if thing.sort() (or reverse or append) were to return the sorted > (reversed, appended) object instead, every existing line like that would > start producing output. Yeech! > O.K. So, besides that ONE *little* problem <embarassed grin :-> what's wrong? And yes - the obvious work around has ocurred to me, and I've used it a few times. But if *I* feel the need to redefine sort, and _if_ you and others also feel it is awkward ( I don't know if that IS the case ), then I'd say it IS a mis-feature. ( though clearly not as easy to fix transparently as I had thought. ) Honestly - this has not been a major problem for me. One reasone I'm bringing it up is that python release 0.9.9, as well as the "Great Renaming" has me thinking about becomming a more active "Python Evangelist". We've been through a couple of syntax changes, but I have sort of assumed that by the time we get to version 1.0 release, the language, ( if not the implementation ) will essentially be stable. ( with perhaps some upwardly compatible extensions. ) So the approach of that event has made me a bit "picky" - I feel it's "speak now or forever hold your peace!" And I feel that this is one of the "non-intuitive" features of python that new users might stumble over a few times. [ The same goes for my pickiness about "array.read( file, count )" ] Which is also why I'm concerned with the normal default bahaviour, rather than how I can fix it for me. I'm not sure if I can transparently change the default behaviour without having to remember to import MY definitions - maybe I can do it with an init file, so that it gets imported into the global namespace. Certainly, I could change C source and rebuild *MY* copy of python to do what *I* want. But then I'ld just get used to ( and learn to take for granted ) what for everyone ELSE is the wrong behaviour. I don't think it bugs me THAT much, that I'ld become an island among python users. ( Any idea how many of us there are? ) [ Although, I might be tempted to try it as an experiment, to see HOW many pieces of code the change might actually break, and how badly. ] - Steve M. Received: from schelvis.cwi.nl by charon.cwi.nl with SMTP id AA26157 (5.65b/3.10/CWI-Amsterdam); Tue, 14 Sep 1993 10:32:49 +0200 Received: by schelvis.cwi.nl with SMTP id AA28658 (5.65b/3.8/CWI-Amsterdam); Tue, 14 Sep 1993 10:32:49 +0200 Message-Id: <9309140832.AA28658=jack@schelvis.cwi.nl> To: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Cc: python-list@cwi.nl Subject: Re: My other pet python peeve - .sort(),.reverse(), etc. return None In-Reply-To: Message by "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> , Mon, 13 Sep 1993 14:23:19 -0400 , <199309131823.AA13074@elvis.med.Virginia.EDU> Organisation: Multi-media group, CWI, Kruislaan 413, Amsterdam Phone: +31 20 5924098(work), +31 20 5924199 (fax), +31 20 6160335(home) X-Last-Band-Seen: Luka Bloom (Paradiso, 13-9) X-Mini-Review: A grand way to start the weekend! Date: Tue, 14 Sep 1993 10:32:48 +0200 From: Jack Jansen <Jack.Jansen@cwi.nl> Recently, "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> said: > ( And I can't even think of some likely + reasonable code that would > be broken by the change. I can't think that anyone ever *tests* > that "list.sort() == None" - since that is, in fact, the only > possible return value. ) > Well, if all my programs that use list.sort() suddenly start spouting output all over the place, I would consider that "broken". It wouldn't be the kind of thing that is difficult to find, though, especially with the new -k flag. There's another thing I don't like about this, though, and that is the fact that you either have to make sort() only return the sorted list (i.e. leave the original intact), or both return it and update it in-place. The first option *does* have backward-compatability problems (and is less efficient to boot, since the current sort only moves some pointers around), and the second one is not very elegant. -- Jack Jansen | If I can't dance I don't want to be part of Jack.Jansen@cwi.nl | your revolution -- Emma Goldman uunet!cwi.nl!jack G=Jack;S=Jansen;O=cwi;PRMD=surf;ADMD=400net;C=nl Received: from mailgate.ericsson.se by charon.cwi.nl with SMTP id AA06681 (5.65b/3.10/CWI-Amsterdam); Wed, 15 Sep 1993 12:56:54 +0200 Received: from eua.ericsson.se by mailgate.ericsson.se (4.1/SMI-4.1-MAILGATE1.14) id AA06856; Wed, 15 Sep 93 12:54:00 +0200 Received: from ms.eua.ericsson.se by eua.ericsson.se (4.1/EUA-2.1) id AA08340; Wed, 15 Sep 93 12:53:57 +0200 Received: from euas09c18.eua.ericsson.se by ms.eua.ericsson.se (4.1/MS-2.1) id AA04976; Wed, 15 Sep 93 12:53:55 +0200 From: Mats.Lidell@eua.ericsson.se (Mats Lidell) Received: by euas09c18.eua.ericsson.se (4.1/client-1.3) id AA14092; Wed, 15 Sep 93 12:53:54 +0200 Date: Wed, 15 Sep 93 12:53:54 +0200 Message-Id: <9309151053.AA14092@euas09c18.eua.ericsson.se> To: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Cc: Tim Peters <tim@ksr.com>, python-list@cwi.nl, sdm7g@virginia.edu Subject: Re: My other pet python peeve - .sort(),.reverse(), etc. return None In-Reply-To: <199309140708.AA11742@elvis.med.Virginia.EDU> References: <199309140708.AA11742@elvis.med.Virginia.EDU> Comments: Hyperbole mail buttons accepted, v3.07. >>>>> Steven recently wrote: Steven> I don't think it bugs me THAT much, that I'ld become an Steven> island among python users. ( Any idea how many of us there Steven> are? ) Huh... There must be a few others on this list beside you guys. ;-) Well I'm one but I usually only write a script or two the period of a half year. So it is really hard to level with you on these types of detailed discussion. But here goes anyway ... Steven> [ Although, I might be tempted to try it as an experiment, Steven> to see HOW many pieces of code the change might actually Steven> break, and how badly. ] This is a conseptioal problem. As I view (e.g what the gurus brainwashed me to think :-) the OO-world is that it is convenient to think about two kinds or operations that manipulate the objects, Procedures and Functions. Functions return some value but does not change the object and with Procedures it is the opposit. They do not return any value but do indeed manipulate the objekt into a new state. I don't know how stringent this is kept in python but at least I like it. So the solution to Stevens problem would not be to change sort into provide both services but rather to introduce another "function" that would return the sorted value but would not change the originating object. %% Mats Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA00500 (5.65b/3.10/CWI-Amsterdam); Thu, 16 Sep 1993 06:25:06 +0200 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa18355; 16 Sep 93 0:25 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA22362; Thu, 16 Sep 1993 00:24:53 -0400 Date: Thu, 16 Sep 1993 00:24:53 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199309160424.AA22362@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: python-list@cwi.nl Subject: Stupid Python Tricks #2 Re: pet peaves Ok, Tim,Jack,Mats - I give up. I guess I'm just a hopeless C-head! I will even admit, that after looking at the way the topic is introduced in the Tutorial, that it is also not as confusing or arbitrary as I might have thought. Re: exception and error handling And yes, Tim: Python is vastly better that Fortran, C, etc... It's just that I'm such a Python FAN that my expectations are ALSO vastly higher. Also - I enjoy pushing at the edges and finding out what I CAN'T do. What is FUN, is when you discover that things are easier that you had thought. Which brings me to "Stupic Python Trick #2" : I often find myself creating pieces of python code with this idiom: list = [] # start with empty list and fill it while Something : list.append( next_thing() ) -or- string = '' # start with empty string and fill it while Something: string = string + next_token() Sometime I find that I'm creating a what could be a generic function that operates on sequences, but I needed ( or at least wanted ) the function to return the same type of sequence that it had been given. I couldn't figure out a good way to do this, other than checking the type of the args and doing some conditional processing according to the type. But, now, with the ability to create new classes of sequences, that solution is even less satisfactory. Luckily, however, a description of one aspect of the problem points to the solution. Note the relation: type( string ) == type( string[0] ) type( list ) <> type( list[0] ) type( tuple ) <> type( tuple[0] ) i.e. Strings are composed of smaller strings, But tuples and lists contain other things. However, the relation that IS consistent is: type( sequence ) == type( sequence[:0] ) i.e. sequence[:0] is the empty sequence for all sequence types. Which gives us the idion in the following example: ( pace SICP, for the "iterative" recursive function. ) #!/usr/local/bin/python # def reverse( thing ): return revi( thing, thing[:0] ) def revi( a, b ): if not a : return b return revi( a[1:], a[:1]+b ) string = '123456789' list = [ 1,2,3,4,5,6,7,8,9 ] tuple = ( 1,2,3,4,5,6,7,8,9 ) string reverse(string) list reverse(list) tuple reverse(tuple) #------------- which yields: '123456789' '987654321' [1, 2, 3, 4, 5, 6, 7, 8, 9] [9, 8, 7, 6, 5, 4, 3, 2, 1] (1, 2, 3, 4, 5, 6, 7, 8, 9) (9, 8, 7, 6, 5, 4, 3, 2, 1) and should do the same for any user-written, sequence like class. I expect that this momentous discovery is actually burried somewhere in the sources of one of Guido's demo scripts. Well - maybe if we trade some of these simple idioms, I can remind myself that python is NOT C,LISP,Pascal,ICON,Perl, or any other language, and stop complaining about functions vs procedures, etc. Maybe we a creative challenge to see how many different ways we can find to write a simple python program - sort of like the 4000 different ways to print "Just another PERL hacker" that you always see in the sigs on Comp.lang.perl. [ 'Hacker', 'Python', 'another', 'Just' ].reverse() !!! OOPS !!! - It didn't print anything! - Steve Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA22217 (5.65b/3.10/CWI-Amsterdam); Thu, 16 Sep 1993 23:08:20 +0200 Received: by hermix.markv.com id ad09540; 16 Sep 93 14:06 PDT To: python-list@cwi.nl Subject: compile() builtin error catching.. X-Organization: Mark V Systems Ltd. X-Address: 16400 Ventura Blvd Suite 303, Encino, Ca, 91436, USA X-Phone: +1 818 995 7671 (work), +1 818 995 4267 (fax) Date: Thu, 16 Sep 93 12:13:13 PDT From: lance@markv.com Sender: lance@markv.com Message-Id: <9309161213.aa06559@hermix.markv.com> Source-Info: From (or Sender) name not authenticated. I have a program that loads text from an external file and passes it to the builtin Python function compile(). I can put a try:except: statement around it to catch when there ar sntax errors, etc.. BUT I cannot get the LINE number that the error occured on. If I try to take a look at sys.exc_traceback.tb_lineno, it is garbage... How can I get the line number from INSIDE a python program??? I could and MIGHT have to write this part in C, but would prefer NOT to if at all possible.. -- Lance Ellinghouse lance@markv.com 1231 bit key fingerprint = 56 DA 31 0C 17 51 36 6A 4E D4 E0 11 D9 B8 06 0A 1024 bit key fingerprint = 66 2C 75 F2 E9 1C 32 84 3A E3 B0 5E 48 01 4C 37 You can receive my Public Key by `finger lance@markv.com` Received: from boulder.Colorado.EDU by charon.cwi.nl with SMTP id AA25704 (5.65b/3.10/CWI-Amsterdam); Fri, 17 Sep 1993 00:04:25 +0200 Received: from vette.Colorado.EDU by boulder.Colorado.EDU with SMTP id AA03149 (5.65c/IDA-1.4.4 for <@boulder.colorado.edu:python-list@cwi.nl>); Thu, 16 Sep 1993 16:04:20 -0600 Received: by vette.colorado.edu (920330.SGI/911001.SGI) for @boulder.colorado.edu:python-list@cwi.nl id AA04063; Thu, 16 Sep 93 16:04:18 -0600 Date: Thu, 16 Sep 93 16:04:18 -0600 From: michel@vette.colorado.edu (Michel Lesoinne) Message-Id: <9309162204.AA04063@vette.colorado.edu> To: python-list@cwi.nl Subject: Python on Mac I am trying to use python on a mac. I would like to know how I can run a python program directly ? Is it possible to write a file that the Mac will recognize as being a python script ? How can I compile my python script ? Any help will be appreciated! Michel (michel@janus.colorado.edu) Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA01086 (5.65b/3.10/CWI-Amsterdam); Fri, 17 Sep 1993 00:38:49 +0200 To: python-list@cwi.nl Subject: lineno on failed compile() commands... X-Organization: Mark V Systems Ltd. X-Address: 16400 Ventura Blvd Suite 303, Encino, Ca, 91436, USA X-Phone: +1 818 995 7671 (work), +1 818 995 4267 (fax) Date: Thu, 16 Sep 93 15:38:21 PDT From: lance@markv.com Sender: lance@markv.com Message-Id: <9309161538.aa22606@hermix.markv.com> Source-Info: From (or Sender) name not authenticated. Well I looked around the code and saw that there was a way to extract the linenumber that the builtin.compile() command was on when it fails.. But only from the C code and only down inside the parser instead of the compiler... I decided I would hack the code up a little so that if builtin.compile() failed, it would create an attribute called sys.failed_lineno that could be looked at that comtains JUST the line number. This is not the cleanest but will allow me to continue... I would use it like this: try: co = compile(a,'<string>','exec') except SyntaxError, msg: print 'SyntaxError: ' + msg + ' on line #' + `sys.lineno` if anyone has a better idea or way to do it, please let me know... Here are the diffs to allow this.. =================================================================== RCS file: /u/lance/CVS/python/src/parsetok.c,v retrieving revision 1.1.1.1 diff -c -r1.1.1.1 parsetok.c *** 1.1.1.1 1993/09/09 20:58:43 --- parsetok.c 1993/09/16 20:19:17 *************** *** 40,50 **** /* Parse input coming from a string. Return error code, print some errors. */ int ! parsestring(s, g, start, n_ret) char *s; grammar *g; int start; node **n_ret; { struct tok_state *tok = tok_setups(s); int ret; --- 40,51 ---- /* Parse input coming from a string. Return error code, print some errors. */ int ! parsestring(s, g, start, n_ret, lineno) char *s; grammar *g; int start; node **n_ret; + int *lineno; { struct tok_state *tok = tok_setups(s); int ret; *************** *** 54,59 **** --- 55,65 ---- return E_NOMEM; } ret = parsetok(tok, g, start, n_ret); + if (ret == E_TOKEN || ret == E_SYNTAX) { + if (lineno) { + *lineno = tok->lineno; + } + } /* XXX Need a more sophisticated way to report the line number. if (ret == E_TOKEN || ret == E_SYNTAX) { =================================================================== RCS file: /u/lance/CVS/python/src/parsetok.h,v retrieving revision 1.1.1.1 diff -c -r1.1.1.1 parsetok.h *** 1.1.1.1 1993/09/09 20:58:43 --- parsetok.h 1993/09/16 20:19:18 *************** *** 30,36 **** /* Parser-tokenizer link interface */ ! extern int parsestring PROTO((char *, grammar *, int start, node **n_ret)); extern int parsefile PROTO((FILE *, char *, grammar *, int start, char *ps1, char *ps2, node **n_ret)); --- 30,36 ---- /* Parser-tokenizer link interface */ ! extern int parsestring PROTO((char *, grammar *, int start, node **n_ret, int *lineno)); extern int parsefile PROTO((FILE *, char *, grammar *, int start, char *ps1, char *ps2, node **n_ret)); =================================================================== RCS file: /u/lance/CVS/python/src/pythonrun.c,v retrieving revision 1.1.1.1 diff -c -r1.1.1.1 pythonrun.c *** 1.1.1.1 1993/09/09 20:57:38 --- pythonrun.c 1993/09/16 22:10:05 *************** *** 267,273 **** { node *n; int err; ! err = parse_string(str, start, &n); return run_err_node(err, n, "<string>", globals, locals); } --- 267,273 ---- { node *n; int err; ! err = parse_string(str, start, &n, 0); return run_err_node(err, n, "<string>", globals, locals); } *************** *** 334,342 **** node *n; int err; codeobject *co; ! err = parse_string(str, start, &n); if (err != E_DONE) { err_input(err); return NULL; } co = compile(n, filename); --- 334,347 ---- node *n; int err; codeobject *co; ! int lineno; /* If error, this holds line number of failure */ ! /* make sure "failed_lineno" does not exist incase things work ok */ ! sysset("failed_lineno",NULL); ! err = parse_string(str, start, &n, &lineno); if (err != E_DONE) { err_input(err); + /* Set "failed_lineno" so you can capture line of failure */ + sysset("failed_lineno",newintobject(lineno)); return NULL; } co = compile(n, filename); *************** *** 364,375 **** /* Simplified interface to parsestring */ int ! parse_string(str, start, n_ret) char *str; int start; node **n_ret; { ! int err = parsestring(str, &gram, start, n_ret); /* Don't confuse early end of string with early end of input */ if (err == E_EOF) err = E_SYNTAX; --- 369,381 ---- /* Simplified interface to parsestring */ int ! parse_string(str, start, n_ret, lineno) char *str; int start; node **n_ret; + int *lineno; { ! int err = parsestring(str, &gram, start, n_ret, lineno); /* Don't confuse early end of string with early end of input */ if (err == E_EOF) err = E_SYNTAX; =================================================================== RCS file: /u/lance/CVS/python/src/pythonrun.h,v retrieving revision 1.1.1.1 diff -c -r1.1.1.1 pythonrun.h *** 1.1.1.1 1993/09/09 20:58:42 --- pythonrun.h 1993/09/16 20:19:19 *************** *** 39,45 **** int run_tty_1 PROTO((FILE *, char *)); int run_tty_loop PROTO((FILE *, char *)); ! int parse_string PROTO((char *, int, struct _node **)); int parse_file PROTO((FILE *, char *, int, struct _node **)); object *eval_node PROTO((struct _node *, char *, object *, object *)); --- 39,45 ---- int run_tty_1 PROTO((FILE *, char *)); int run_tty_loop PROTO((FILE *, char *)); ! int parse_string PROTO((char *, int, struct _node **, int *)); int parse_file PROTO((FILE *, char *, int, struct _node **)); object *eval_node PROTO((struct _node *, char *, object *, object *)); -- Lance Ellinghouse lance@markv.com 1231 bit key fingerprint = 56 DA 31 0C 17 51 36 6A 4E D4 E0 11 D9 B8 06 0A 1024 bit key fingerprint = 66 2C 75 F2 E9 1C 32 84 3A E3 B0 5E 48 01 4C 37 You can receive my Public Key by `finger lance@markv.com` Received: from hopscotch.ksr.com by charon.cwi.nl with SMTP id AA14514 (5.65b/3.10/CWI-Amsterdam); Fri, 17 Sep 1993 04:08:33 +0200 Received: from ksr.com (frankenstein.ksr.com) by hopscotch.ksr.com with SMTP id AA05446; Thu, 16 Sep 1993 22:08:33 -0400 Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA10473; Thu, 16 Sep 93 22:08:28 EDT Received: by kaos.ksr.com (4.1/KSR-2.0) id AA15722; Thu, 16 Sep 93 22:08:19 EDT Message-Id: <9309170208.AA15722@kaos.ksr.com> To: sdm7g@virginia.edu, python-list@cwi.nl Subject: Re: Stupid Python Tricks #2 Date: Thu, 16 Sep 93 22:08:18 -0400 From: Tim Peters <tim@ksr.com> "Python tricks" is a tough one, cuz the language is so clean. E.g., C makes an art of confusing pointers with arrays and strings, which leads to lotsa neat pointer tricks; APL mistakes everything for an array, leading to neat one-liners; and Perl confuses everything period, making each line a joyous adventure <wink>. I've seen Python criticized as "ugly" precisely because it _doesn't_ have a trick-based view of the world. In many ways, it's a dull language, borrowing solid old concepts from many other languages & styles: boring syntax, unsurprising semantics, few automatic coercions, etc etc. But that's one of the things I like about it. The trickiest areas in my experience have to do with namespace management, both the cool way classes introduce dynamic new namespaces, and the way assignment in general merely binds a name to an object. You can do some very powerful things after grasping these, but they're already illustrated well in the distributed Python samples. The most practical-- but mundane --"trick" I've stumbled into is a speed trick, when using a dict to accumulate info, and accesses to existing keys outnumber new keys. E.g., try: dict[key] = dict[key] + 1 except KeyError: dict[key] = 0 can run a good deal faster than if dict.has_key(key): dict[key] = dict[key] + 1 else: dict[key] = 0 I imagine that's because the latter looks up the key 3 times, instead of twice in the former, in the usual (the key is usually present, by supposition) case. But then putting a little smarts into the translator would allow either form to map into runtime code that did only 1 key lookup. What I'd _really_ like to write is (a la C, Icon, Perl, etc) try: dict[key] += 1 # hypothetical augmented assignment operator '+=' except KeyError: dict[key] = 0 I.e., to be able to write it in a way that a mindless translator would usually map to a single key lookup. > ... > challenge to see how many different ways we can find to write a > simple python program - sort of like the 4000 different ways to > print "Just another PERL hacker" that you always see in the sigs > on Comp.lang.perl. Hey, I'm game <grin>! Here's another way to write reverse: def rev( x ): l2 = len(x)/2 if l2: return rev(x[l2:]) + rev(x[:l2]) else: return x It works for strings/tuples/lists/user_sequences, and has the practical advantage that the call stack doesn't grow deeper than log2(len(x)). >>> rev((rev('rekcah'),rev('nohtyP'),rev('rehtona'),rev('tsuJ'))) ('Just', 'another', 'Python', 'hacker') >>> even-obfuscated-python's-darned-easy-to-read-ly y'rs - tim Tim Peters tim@ksr.com not speaking for Kendall Square Research Corp Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA18792 (5.65b/3.10/CWI-Amsterdam); Fri, 17 Sep 1993 16:44:48 +0200 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa14392; 17 Sep 93 10:43 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA19247; Fri, 17 Sep 1993 10:15:58 -0400 Date: Fri, 17 Sep 1993 10:15:58 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199309171415.AA19247@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: Michel Lesoinne <michel@vette.colorado.edu> Subject: Re: Python on Mac Cc: python-list@cwi.nl Well - I haven't used the Mac Python for a while so I'm not sure, but generally, Mac documents have a TYPE field and a CREATOR field. If you write a python script with an Mac editor, the TYPE field will be set to 'TEXT' ( assuming you save it AS text, and not some native format ) and the CREATOR will be the Editor program. The creator field is used to tell the system what program to launch when the document is clicked on. So if you change the creator field to the field for Python ( does anyone happen to know what that is? ) then the system will launch python when you click on that file. It is then up to the application ( PYTHON ) to recognize that it has been given an initial event ( a file open event ) and open and read that file. I don't happen to know if Mac Python does this. If I get a chance to sit in front of a Mac for a while, I'll give it a test. Does Mac Python generate .pyc files ? and are they set to creator=Python ? If that is the case, then the .pyc files should be 'clickable' applications. -Steve Majewski (804-982-0831) <sdm7g@Virginia.EDU> -Univ. of Virginia Department of Molecular Physiology and Biological Physics Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA01309 (5.65b/3.10/CWI-Amsterdam); Fri, 17 Sep 1993 18:43:46 +0200 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa29145; 17 Sep 93 12:43 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA22013; Fri, 17 Sep 1993 12:30:49 -0400 Date: Fri, 17 Sep 1993 12:30:49 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199309171630.AA22013@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: Tim Peters <tim@ksr.com>, sdm7g@virginia.edu, python-list@cwi.nl Subject: Re: Stupid Python Tricks #2 On Sep 16, 22:08, Tim Peters wrote: > > "Python tricks" is a tough one, cuz the language is so clean. E.g., C > makes an art of confusing pointers with arrays and strings, which leads > to lotsa neat pointer tricks; APL mistakes everything for an array, > leading to neat one-liners; and Perl confuses everything period, making > each line a joyous adventure <wink>. > I agree, Tim. Clearly, my 'Obfuscated Python' subject line was meant tongue in cheek - as in, "this is about as obfuscated as I can get in python". Well - not quite, since you managed to top me with: [ from an earlier email message: ] > > while exec('x=stdin.readline()') or (x and (stdout.write(process(x)) or x)): > pass > > is clearly the _correct_ way to do it <grin>. > > I've seen Python criticized as "ugly" precisely because it _doesn't_ have > a trick-based view of the world. In many ways, it's a dull language, > borrowing solid old concepts from many other languages & styles: boring > syntax, unsurprising semantics, few automatic coercions, etc etc. But > that's one of the things I like about it. > > The trickiest areas in my experience have to do with namespace > management, both the cool way classes introduce dynamic new namespaces, > and the way assignment in general merely binds a name to an object. You > can do some very powerful things after grasping these, but they're > already illustrated well in the distributed Python samples. Well - sometimes there are "suprising semantics" introduced by the namespace management.(*) So if we TRULY want to write some obfuscated python, it should clearly do something subtle with the name space, or tricky 'eval' or 'compiles' of generated strings, or Classes that define non-intuitive meanings for '+' or '[i]' . So, yes, you CAN write _REALLY_ obfuscated python, but you have to go quite out of your way to make the effort. ( As opposed to 'C', where you have to go quite out of your way to un-obfuscate it! ) [ (*) Recall the confusion I had long ago with module global names - it has since been "fixed" with 'global' and a couple of other changes, but it was, I recall a very subtle and interesting side effect of the python namespace. ] > > even-obfuscated-python's-darned-easy-to-read-ly y'rs - tim > But I wouldn't describe python as "dull" ! One of the things that makes it interesting, is exactly how much Guido has managed to exploit that *one* implementation trick of 'namespaces'. Python is built around the concept of namespace - just as arrays are at the core of APL and lists/S-expr's are the secret of the power of LISP. And as a result, I think it makes it a quite comprehensible language. I don't often have time to read thru the python sources, but I still feel I have a sort-of-basic understanding of how things work "under-the-hood" . FORTH and LISP both have a very simple, comprehensible core language upon which a much more elaborate system is constructed. FORTH is built around threaded-code and dictionaries ( which, unsuprisingly, can be made to do some similar things as python's namespaces - there are FORTH words which change the dictionary search order, and thus the context for evaluation of following words. ) Lisp is built upon lists and the read-eval-print of S-expressions. Python is a bit more complicated, but much of that complication is just (as they say) "surface syntax". In python - everything is an object, and a name is turned into an object via dictionary lookup in the namespace of the current context. Modules and classes both create new namespaces, and reference to a module or a class instance changes the evaluation context. This simplicity counts for a lot when you DO need to extend or embed the interpreter. We have seen a number of posts to this list about 'I changed python to do this...' ( the most recent being Lance's addition of line number error tracing to 'compile()' ) The idea of adding a new data type to python doesn't scare me. ( The only thing I thought I might actually need was arrays, to make more effecient passing to and from a C program that would have an embedded python interpreter - but someone else has already done that - Thanks guys! ) Some of this is due to the level of documentation that Guido has supplied, but a lot of it is due to starting with a clean design and a simple concept. I have never looked "under-the-hood" at perl in nearly as much detail - the surface frightened me off! -Steve Majewski (804-982-0831) <sdm7g@Virginia.EDU> -Univ. of Virginia Department of Molecular Physiology and Biological Physics Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA03818 (5.65b/3.10/CWI-Amsterdam); Fri, 17 Sep 1993 20:27:13 +0200 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa01285; 17 Sep 93 12:56 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA19994; Fri, 17 Sep 1993 12:56:38 -0400 Date: Fri, 17 Sep 1993 12:56:38 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199309171656.AA19994@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: Tim Peters <tim@ksr.com>, sdm7g@virginia.edu, python-list@cwi.nl Subject: Other tricks with dictionaries ( was Stupid Python Trick #2 ) I pretty much ignored the discussion that followed the proposal that dictionary mappings be extended to have keys other that type string. I really didn't see a need for them myself ( at the time ) - you could always use `thing` as the key string. But now that they ARE arbitrarily indexable - I have discovered that the REALLY neat thing is that dictionaries are now INVERTABLE. This is sometimes and easy solution to an awkward problem. Please excuse me if this was the obvious point of the whole proposal. I may have been too dense at the time to figure that out, but it now looks like such an obvious trick now, that I have even used it when it wasn't necessary: i.e. the special case where I was mapping from strings to integers, could be reverse mapped with a list of strings where list.index( 'string' ) == dict['string']. The more general solution of building an inverse dictionary may have much wider uses. -Steve Majewski (804-982-0831) <sdm7g@Virginia.EDU> -Univ. of Virginia Department of Molecular Physiology and Biological Physics Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA03682 (5.65b/3.10/CWI-Amsterdam); Fri, 17 Sep 1993 20:22:24 +0200 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa13657; 17 Sep 93 14:22 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA23257; Fri, 17 Sep 1993 14:22:14 -0400 Date: Fri, 17 Sep 1993 14:22:14 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199309171822.AA23257@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: Tim Peters <tim@ksr.com>, sdm7g@virginia.edu, python-list@cwi.nl Subject: virtues and simplicity of python ( was: Stupid Python Tricks #2 ) But I'm sure I'm just preaching to the converted here! Maybe I should post that to comp.lang.misc or someplace. The list is nice because we avoid all of the language wars and flames, but I think we DO need to do a bit of advertising once and a while. - Steve M. Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA06309 (5.65b/3.10/CWI-Amsterdam); Fri, 17 Sep 1993 22:43:10 +0200 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa01518; 17 Sep 93 16:43 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA13194; Fri, 17 Sep 1993 16:43:01 -0400 Date: Fri, 17 Sep 1993 16:43:01 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199309172043.AA13194@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: python-list@cwi.nl Subject: My other pet python peeve - .sort(),.reverse(), etc. return None Silly me! My "Silly Python Trick #2" provides the obvious solution to the general problem of wanting a procedure that also return an updated object: ( thing.procedural_method() or thing ) ==> updated thing as in: >>> b = [] >>> for c in 'aBcDeFg' : Z = ( b.append(c) or b.reverse() or b ) ... else: Z ... ['g', 'e', 'c', 'a', 'B', 'D', 'F'] >>> BTW: The parends are necessary for: ( 1 or 2 ) >>> 1 or 2 Parsing error: file <stdin>, line 1: 1 or 2 ^ SyntaxError: invalid syntax >>> ( 1 or 2 ) 1 Is this just an residue of the days when the parser had to distinguish between boolean and binding "=", or does it fulfill some other syntactical need ? - Steve M. Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA06522 (5.65b/3.10/CWI-Amsterdam); Fri, 17 Sep 1993 23:33:38 +0200 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa09534; 17 Sep 93 17:33 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA21517; Fri, 17 Sep 1993 17:33:24 -0400 Date: Fri, 17 Sep 1993 17:33:24 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199309172133.AA21517@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: python-list@cwi.nl Subject: obfuscated python Of course, in the intentional obfuscation category, there is always: >>> a = range( 1, 11 ) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> ( eval( 'a.'+[].__methods__[-2] )() or a ) # ( take a guess ... ) [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] or maybe: >>> import sys >>> eval( eval( 'dir()[-1]', sys.__dict__ ), sys.__dict__ ) '0.9.9 (Sep 7 1993)' And numerous other ways to avoid actually naming the act! - Steve M. Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA10815 (5.65b/3.10/CWI-Amsterdam); Sat, 18 Sep 1993 00:25:11 +0200 To: python-list@cwi.nl Subject: FTP site for Python scripts X-Organization: Mark V Systems Ltd. X-Address: 16400 Ventura Blvd Suite 303, Encino, Ca, 91436, USA X-Phone: +1 818 995 7671 (work), +1 818 995 4267 (fax) Date: Fri, 17 Sep 93 15:23:36 PDT From: lance@markv.com Sender: lance@markv.com Message-Id: <9309171523.aa03097@hermix.markv.com> Source-Info: From (or Sender) name not authenticated. I have created 2 directories on our FTP site for people to place Python script files as well as get any that people place there.. The site is: ftp.markv.com (192.122.251.1) The place to put them is in /incoming/python The place they will be put for general usage is /pub/python The /incoming/python directory is a drop directory.. you cannot do a directory listing of it.. If you place any files in there, please either upload a file.readme file to explain what the file(s) do and I will place that description along with the actual files.. I will also maintain a file that contains a short description as well as who uploaded it (if that info is in the readme file or Emailed)... Currently I don't know of any FTP site that is acting as a repository of script files for python besides Guido's. Let's start exchanging ideas and code.. I will be placing a couple modules I have into these directories for a starting place to build from.. If there is enough interest and enough is posted to this location, I will also post to this mailing list the summary file every now and then. -- Lance Ellinghouse lance@markv.com 1231 bit key fingerprint = 56 DA 31 0C 17 51 36 6A 4E D4 E0 11 D9 B8 06 0A 1024 bit key fingerprint = 66 2C 75 F2 E9 1C 32 84 3A E3 B0 5E 48 01 4C 37 You can receive my Public Key by `finger lance@markv.com` Received: from hopscotch.ksr.com by charon.cwi.nl with SMTP id AA02744 (5.65b/3.10/CWI-Amsterdam); Sun, 19 Sep 1993 06:42:11 +0200 Received: from ksr.com (frankenstein.ksr.com) by hopscotch.ksr.com with SMTP id AA08615; Sun, 19 Sep 1993 00:40:54 -0400 Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA25771; Sun, 19 Sep 93 00:42:15 EDT Received: by kaos.ksr.com (4.1/KSR-2.0) id AA15213; Sun, 19 Sep 93 00:42:12 EDT Message-Id: <9309190442.AA15213@kaos.ksr.com> To: sdm7g@virginia.edu, python-list@cwi.nl Subject: Re: obfuscated python Date: Sun, 19 Sep 93 00:42:12 -0400 From: Tim Peters <tim@ksr.com> > >>> b = [] > >>> for c in 'aBcDeFg' : Z = ( b.append(c) or b.reverse() or b ) > ... else: Z > >>> ( eval( 'a.'+[].__methods__[-2] )() or a ) > >>> import sys > >>> eval( eval( 'dir()[-1]', sys.__dict__ ), sys.__dict__ ) Oh, bletch! Those are disgusting, Steve. I can't compete at this level of perversity, but I do encourage you to keep up the delightfully revolting work <smile>. > >>> 1 or 2 > Parsing error: file <stdin>, line 1: > 1 or 2 > ^ > SyntaxError: invalid syntax > >>> ( 1 or 2 ) > 1 > > Is this just an residue of the days when the parser had > to distinguish between boolean and binding "=", or does > it fulfill some other syntactical need ? These behaviors still follow from the formal syntax in the reference manual, but I'm not sure they _need_ to anymore (I too recall them stemming from the need to disambiguate a=b=c back in the days when "=" was the both the equality and the assignment operator). I often get burned by this variation too: for i in 1,2,3: is legit, but if i in 1,2,3: is a syntax error (needs to be if i in (1,2,3): or a moral equivalent instead). And the following is a very subtle oops-you-really-wanted-a-tuple there mistake (subtle because it's not a syntax error): try: some_code() except ZeroDivisionError, NameError: pass I.e., if some_code() does raise ZeroDivisionError, the name NameError gets bound to 'integer division or modulo' (the "detail" of the ZeroDivisionError), and so any subsequent attempt to catch NameError will fail. It took an awful long time to figure out what went wrong when (something similar to) this bit me in a real program. But I don't complain, because it broke me of the bad habit of relying on catching exceptions <0.9 grin>. thank-god-i-still-smoke-ly y'rs - tim, grateful for one vice Tim Peters tim@ksr.com not speaking for Kendall Square Research Corp Received: from hopscotch.ksr.com by charon.cwi.nl with SMTP id AA05053 (5.65b/3.10/CWI-Amsterdam); Sun, 19 Sep 1993 07:29:56 +0200 Received: from ksr.com (frankenstein.ksr.com) by hopscotch.ksr.com with SMTP id AA08653; Sun, 19 Sep 1993 01:28:34 -0400 Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA26124; Sun, 19 Sep 93 01:29:54 EDT Received: by kaos.ksr.com (4.1/KSR-2.0) id AA15356; Sun, 19 Sep 93 01:29:50 EDT Message-Id: <9309190529.AA15356@kaos.ksr.com> To: sdm7g@virginia.edu, python-list@cwi.nl Subject: Re: Other tricks with dictionaries Date: Sun, 19 Sep 93 01:29:50 -0400 From: Tim Peters <tim@ksr.com> Ya, invertibility is good stuff! There are a couple other reasons for wanting general keys: 1) Possibility. Python can't build a string representation for a structure with loops, so the `make_key_a_string` idiom didn't always work. Along with the new id() function, dicts can now (with a little care) be indexed by anything. 2) Efficiency. Computing a string representation can be arbitrarily expensive. E.g., consider a class instance that carries a lot of state. Or just long integers (`longint` takes time quadratic in the length of the string). 3) Convenience. E.g., needing to backquote integer keys was an irritation. > The more general solution of building an inverse dictionary may have > much wider uses. A random one came up the other day, while prototyping a register assigner: 1) Given such & such a register, which expression does it currently contain? 2) Given a specific expression, in which register(s) can it currently be found? Of course there are _lots_ of mappings that are interesting in both directions, and a pair of "mirror" dicts is a pleasant way to deal with 'em. happily y'rs - tim Tim Peters tim@ksr.com not speaking for Kendall Square Research Corp Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA07895 (5.65b/3.10/CWI-Amsterdam); Mon, 20 Sep 1993 22:10:09 +0200 From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: python-list@cwi.nl Subject: classes or scripts for FTP site?? Date: Mon, 20 Sep 93 13:09:24 PDT Message-Id: <9309201309.aa12858@hermix.markv.com> Does anyone have any classes or scripts that can be placed on the FTP site? How about new C code modules? Lance Ellinghouse lance@markv.com Replied: Wed, 22 Sep 1993 23:37:54 +0200 Replied: lance@markv.com Replied: python-list@cwi.nl Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA17131 (5.65b/3.10/CWI-Amsterdam); Wed, 22 Sep 1993 23:03:31 +0200 To: python-list@cwi.nl Subject: TERMIO.py ??? X-Organization: Mark V Systems Ltd. X-Address: 16400 Ventura Blvd Suite 303, Encino, Ca, 91436, USA X-Phone: +1 818 995 7671 (work), +1 818 995 4267 (fax) Date: Wed, 22 Sep 93 14:02:19 PDT From: lance@markv.com Sender: lance@markv.com Message-Id: <9309221402.aa26578@hermix.markv.com> Source-Info: From (or Sender) name not authenticated. hello... I cannot seem to find TERMIO.py anywhere.. Where can I get it? any pointers?? Thanks -- Lance Ellinghouse lance@markv.com 1231 bit key fingerprint = 56 DA 31 0C 17 51 36 6A 4E D4 E0 11 D9 B8 06 0A 1024 bit key fingerprint = 66 2C 75 F2 E9 1C 32 84 3A E3 B0 5E 48 01 4C 37 You can receive my Public Key by `finger lance@markv.com` Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA17385 (5.65b/3.10/CWI-Amsterdam); Wed, 22 Sep 1993 23:36:38 +0200 Received: from [138.95.9.34] by gateway.sequent.com (5.61/1.34) id AA07043; Wed, 22 Sep 93 14:37:07 -0700 Received: from ushqgw1.sequent.com by relay1.sequent.com (5.65/crg/11) id AA29206; Wed, 22 Sep 93 14:39:23 -0700 Received: by ushqgw.sequent.com with Microsoft Mail id <2CA0C4A3@ushqgw.sequent.com>; Wed, 22 Sep 93 14:33:23 PDT From: "Jaap Vermeulen (jaap)" <jaap@sequent.com> To: lance <lance@markv.com>, python-list <python-list@cwi.nl> Subject: RE: TERMIO.py ??? Date: Wed, 22 Sep 93 14:31:00 PDT Message-Id: <2CA0C4A3@ushqgw.sequent.com> Encoding: 15 TEXT X-Mailer: Microsoft Mail V3.0 | I cannot seem to find TERMIO.py anywhere.. Where can I get it? | any pointers?? I just made one from scratch, since these kinds of files may be system specific. Guido wrote a little script in one of the demo directories (something like h2py) to process a header file and turn it into a python module. Although not complete, it mostly does the job, with some manual edits afterwards. In general, if Python is going to provide lower level functionality such as fcntl and ioctl (which I argued for and like very much), it should also provide some fully functional header rewriting script, like Perl. At least twice I started writing a script like that but never finished. :-) -Jaap- Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA17403 (5.65b/3.10/CWI-Amsterdam); Wed, 22 Sep 1993 23:37:53 +0200 Received: by voorn.cwi.nl with SMTP id AA09374 (5.65b/3.8/CWI-Amsterdam); Wed, 22 Sep 1993 23:37:53 +0200 Message-Id: <9309222137.AA09374=guido@voorn.cwi.nl> To: lance@markv.com Cc: python-list@cwi.nl Subject: Re: TERMIO.py ??? In-Reply-To: Your message of "Wed, 22 Sep 1993 14:02:19 MDT." <9309221402.aa26578@hermix.markv.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Wed, 22 Sep 1993 23:37:52 +0200 Sender: Guido.van.Rossum@cwi.nl Hmm, can't find it either. But I can't remember where it's being used either. It's probably the result of running <termio.h> through the h2py.py script (demo/scripts), possibly followed by a little manual fiddling... --Guido Replied: Fri, 24 Sep 1993 11:48:23 +0200 Replied: "michel@vette.colorado.edu (Michel Lesoinne) python-list@cwi.nl" Received: from boulder.Colorado.EDU by charon.cwi.nl with SMTP id AA13587 (5.65b/3.10/CWI-Amsterdam); Thu, 23 Sep 1993 22:09:18 +0200 Received: from vette.Colorado.EDU by boulder.Colorado.EDU with SMTP id AA27891 (5.65c/IDA-1.4.4 for <@boulder.colorado.edu:python-list@cwi.nl>); Thu, 23 Sep 1993 14:09:03 -0600 Received: by vette.colorado.edu (920330.SGI/911001.SGI) for @boulder.colorado.edu:python-list@cwi.nl id AA13685; Thu, 23 Sep 93 14:08:45 -0600 Date: Thu, 23 Sep 93 14:08:45 -0600 From: michel@vette.colorado.edu (Michel Lesoinne) Message-Id: <9309232008.AA13685@vette.colorado.edu> To: python-list@cwi.nl Subject: duplicate of classes (deep copy) I am trying to write a program that uses fcntl.ioctl to change the condition of a modem line and then at the end reset it to its original value. Is there a simple function in python of all classes that does a deep copy of an instance, similarily to dup in smalltalk. For example I'd like the following to work correctly: tio = Termio() tio.getfrom(0) # performs a TCGETA on file 0 oldtio = tio.dup() #Here it is. of course I can write the dup funtion but # it would be nice if all classes had it so that #it would recursively apply to members tio.lflag = 0 ; tio.iflag = IGNBRK ; tio.oflag = 0 ; tio.setto(0) # Change the line ... # do whatever work oldtio.setto(0) # reset line condition to original value Thanks for any hints. Michel Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA27500 (5.65b/3.10/CWI-Amsterdam); Fri, 24 Sep 1993 11:48:23 +0200 Received: by voorn.cwi.nl with SMTP id AA13556 (5.65b/3.8/CWI-Amsterdam); Fri, 24 Sep 1993 11:48:23 +0200 Message-Id: <9309240948.AA13556=guido@voorn.cwi.nl> To: michel@vette.colorado.edu (Michel Lesoinne) Cc: python-list@cwi.nl Subject: Re: duplicate of classes (deep copy) In-Reply-To: Your message of "Thu, 23 Sep 1993 14:08:45 MDT." <9309232008.AA13685@vette.colorado.edu> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Fri, 24 Sep 1993 11:48:23 +0200 Sender: Guido.van.Rossum@cwi.nl Michel Lesoinne writes: > I am trying to write a program that uses fcntl.ioctl to change the condition > of a modem line and then at the end reset it to its original value. > Is there a simple function in python of all classes that does a deep > copy of an instance, similarily to dup in smalltalk. > For example I'd like the following to work correctly: > > tio = Termio() > tio.getfrom(0) # performs a TCGETA on file 0 > oldtio = tio.dup() #Here it is. of course I can write the dup funtion but > # it would be nice if all classes had it so that > #it would recursively apply to members > tio.lflag = 0 ; > tio.iflag = IGNBRK ; > tio.oflag = 0 ; > > tio.setto(0) # Change the line > > ... # do whatever work > > oldtio.setto(0) # reset line condition to original value No, there isn't such a feature. In the light of Python's varying object semantics (different for each type), deep copies are rarely as useful as one would initially think they would be: they tend to copy either too much or not enough, and sometimes both at the same time. You are better off defining an operation that does exactly what you need in a particular case. Also note that a naive deep copy can get in trouble if there are reference loops. I don't know how smalltalk solves this. Probably by keeping track of objects already copied during the deep copy? But I presume it will also be possible to override the dup method for a particular class, which may spoil the administration used... Anyway, if you want a deep copy, here's something that should work reasonably well. ------------------------------------------------------------------------------- # Make this class a base class of each class you define class UniversalBase: def dup(self): return dupinstance(self) # Function to duplicate an instance def dupinstance(x): new = x.__class__() for key in x.__dict__.keys(): setattr(new, key, dup(getattr(x, key))) return new ClassInstanceType = type(UniversalBase()) # Function to duplicate most object instances def dup(x): if hasattr(x, dup): return x.dup() if type(x) is type(()): new = () for item in x: new = new + (dup(item),) return new if type(x) is type([]): new = [] for item in x: new.append(dup(item)) return new if type(x) is ClassInstanceType: return dupinstance(x) return x # Assume all other interesting types are immutable # Not completely true but reasonable in most cases ------------------------------------------------------------------------------- One problem with this: if a class has an __init__() method, it will be called by the "x.__class__()" in dupinstance(). This may or may not be what is desired; moreover it will fail with probablility one if the __init__() takes one or more arguments. The effect is that classes with such an __init__() method are forced to define their own dup() method (which still will call the __init__() method, but can call it with the proper arguments. Possibly it can be given a special argument signalling to initialize the object from a similar one, like copy constructors in C++. Note that this problem has similarities with the problems one encouters when trying to implement generic persistent objects in Python. There, too, one of the problems is to define what the semantics should be in the light of objects that may contain references to open files, windows, network connections, etc., and to what extent sharing of sub-objects is incidental or essential. I have a feeling that this is because Python mixes mutable and immutable objects and also allows "opaque" objects with arbitrary semantics (e.g. defined by extension modules). Maybe Jaap has some thoughts or opinions on this? --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> PS: Some very interesting issues were raised on the list while I am away. I have read and saved everything and intend to come back to these, if and when I have a little more time... Bear with me... Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA09973 (5.65b/3.10/CWI-Amsterdam); Sat, 25 Sep 1993 00:07:06 +0200 To: python-list@cwi.nl Subject: dos version of 0.9.9 ??? X-Organization: Mark V Systems Ltd. X-Address: 16400 Ventura Blvd Suite 303, Encino, Ca, 91436, USA X-Phone: +1 818 995 7671 (work), +1 818 995 4267 (fax) Date: Fri, 24 Sep 93 15:06:36 PDT From: lance@markv.com Sender: lance@markv.com Message-Id: <9309241506.aa12517@hermix.markv.com> Source-Info: From (or Sender) name not authenticated. has anyone compiled a 0.9.9 version of Python yet? -- Lance Ellinghouse lance@markv.com 1231 bit key fingerprint = 56 DA 31 0C 17 51 36 6A 4E D4 E0 11 D9 B8 06 0A 1024 bit key fingerprint = 66 2C 75 F2 E9 1C 32 84 3A E3 B0 5E 48 01 4C 37 You can receive my Public Key by `finger lance@markv.com` Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA10855 (5.65b/3.10/CWI-Amsterdam); Sat, 25 Sep 1993 02:00:29 +0200 From: Lance Ellinghouse <lance@markv.com> X-Mailer: SCO System V Mail (version 3.2) To: python-list@cwi.nl Subject: rfc822 parser? Date: Fri, 24 Sep 93 16:59:19 PDT Message-Id: <9309241659.aa20763@hermix.markv.com> Has anyone updated or come out with a more complete RFC822 parser then the rfc822.py file that comes with Python? Lance Ellinghouse lance@markv.com Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA26535 (5.65b/3.10/CWI-Amsterdam); Thu, 30 Sep 1993 20:00:32 +0100 Received: from [138.95.9.34] by gateway.sequent.com (5.61/1.34) id AA08080; Thu, 30 Sep 93 12:01:23 -0700 Received: from ushqgw1.sequent.com by relay1.sequent.com (5.65/crg/11) id AA24604; Thu, 30 Sep 93 11:48:49 -0700 Received: by ushqgw.sequent.com with Microsoft Mail id <2CAB283B@ushqgw.sequent.com>; Thu, 30 Sep 93 11:40:59 PDT From: "Jaap Vermeulen (jaap)" <jaap@sequent.com> To: guido <guido@cwi.nl>, michel <michel@vette.colorado.edu (Michel Lesoinne)> Cc: python-list <python-list@cwi.nl> Subject: Re: duplicate of classes (deep copy) Date: Thu, 30 Sep 93 11:40:00 PDT Message-Id: <2CAB283B@ushqgw.sequent.com> Encoding: 86 TEXT X-Mailer: Microsoft Mail V3.0 | Also note that a naive deep copy can get in trouble if there are | reference loops. I don't know how smalltalk solves this. Probably by | keeping track of objects already copied during the deep copy? But I | presume it will also be possible to override the dup method for a | particular class, which may spoil the administration used... Smalltalk doesn't have deepCopy, only shallowCopy. The regular copy will do a shallowCopy followed by a postCopy (to break dependents and other book keeping you need to do after the copy). You can redefine copy to whatever you like if you need it (with care, of course). | One problem with this: if a class has an __init__() method, it will be | called by the "x.__class__()" in dupinstance(). This may or may not | be what is desired; moreover it will fail with probablility one if the | __init__() takes one or more arguments. The effect is that classes | with such an __init__() method are forced to define their own dup() | method (which still will call the __init__() method, but can call it | with the proper arguments. Possibly it can be given a special | argument signalling to initialize the object from a similar one, like | copy constructors in C++. Smalltalk provides two methods for all basic operations. For new objects, the default method is 'new'. New is redefined by those objects that need additional initialization. However, there is always 'basicNew', which you should *never* redefine. With a structure like that you can circumvent the problems outlines above. BTW: the way that operations like 'new' are redefined is by first calling the same operation in the superclass, and then performing your own initialization. So, if your superclass redefined 'new', the superclass initialization will always happen first. In Python code (just to illustrate): class topObject(): def new(self): return self def basicNew(self): return self def copy(self): new = self.shallowCopy() return new.postCopy() class bar(topObject): def new(self): self = foo.new(self) return self.initialize() instance = bar().new() another_instance = instance.copy() | Note that this problem has similarities with the problems one | encouters when trying to implement generic persistent objects in | Python. There, too, one of the problems is to define what the | semantics should be in the light of objects that may contain | references to open files, windows, network connections, etc., and to | what extent sharing of sub-objects is incidental or essential. I have | a feeling that this is because Python mixes mutable and immutable | objects and also allows "opaque" objects with arbitrary semantics | (e.g. defined by extension modules). Smalltalk solves this by giving object that need it the possibility to 'shutdown' or 'instal' themselves. Given that the current state of Smalltalk is saved in the Smalltalk image, objects such as files and the window subsystem are notified in case the image is saved. They take the necessary precautions, the image gets saved, and then those objects get one of two messages. One is that the current session is still active, and the other is that a new session using the saved image started, which means they have to restore their state. For files, this means that they try to reconnect to all the files that were open when the image was saved. For windows, it means that all windows are reopened at the same place with the same contents. Of course there is some logic in place for conditions, such as restarting the image on a different platform where the files don't exist, or the display has a different size. Like I do with my Smalltalk image all the time. I shuttle it around between UNIX, DOS and Mac. The only thing that differs on these platforms is the virtual machine (binary). So, in a way you get object persistence for free. However, to save objects outside the Smalltalk image, there is the BOSS facility, the Binary Object Storage Stream, which saves objects and all objects they reference unambiguously. | Maybe Jaap has some thoughts or opinions on this? Sorry it took me so long. I was busy. :-) -Jaap- Replied: Mon, 11 Oct 1993 11:10:42 +0100 Replied: "Bill Janssen <janssen@parc.xerox.com> python-list" Received: from alpha.Xerox.COM by charon.cwi.nl with SMTP id AA17715 (5.65b/3.10/CWI-Amsterdam); Sun, 10 Oct 1993 04:06:55 +0100 Received: from holmes.parc.xerox.com ([13.1.100.162]) by alpha.xerox.com with SMTP id <12044>; Sat, 9 Oct 1993 20:06:38 PDT Received: by holmes.parc.xerox.com id <16134>; Sat, 9 Oct 1993 20:06:30 -0700 Received: from Messages.7.15.N.CUILIB.3.45.SNAP.NOT.LINKED.holmes.parc.xerox.com.sun4.41 via MS.5.6.holmes.parc.xerox.com.sun4_41; Sat, 9 Oct 1993 20:06:22 -0700 (PDT) Message-Id: <Mghrki4B0KGWN1=7FW@holmes.parc.xerox.com> Date: Sat, 9 Oct 1993 20:06:22 PDT Sender: Bill Janssen <janssen@parc.xerox.com> From: Bill Janssen <janssen@parc.xerox.com> To: python-list@cwi.nl Subject: Current exception In an exception handler, how does one find out what the exception being handled was? Is it possible? I'd like to write something like: try: foo() except: something(e) where e is the specific exception. Bill ------------- Bill Janssen <janssen@parc.xerox.com> (415) 812-4763 FAX: (415) 812-4777 Xerox Palo Alto Research Center, 3333 Coyote Hill Rd, Palo Alto, CA 94304 URL: http://pubweb.parc.xerox.com/hypertext/people/BillJanssen.html Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA10026 (5.65b/3.10/CWI-Amsterdam); Mon, 11 Oct 1993 11:10:43 +0100 Received: by voorn.cwi.nl with SMTP id AA25021 (5.65b/3.8/CWI-Amsterdam); Mon, 11 Oct 1993 11:10:42 +0100 Message-Id: <9310111010.AA25021=guido@voorn.cwi.nl> To: Bill Janssen <janssen@parc.xerox.com> Cc: python-list@cwi.nl Subject: Re: Current exception In-Reply-To: Your message of "Sat, 09 Oct 1993 20:06:22 MDT." <Mghrki4B0KGWN1=7FW@holmes.parc.xerox.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Mon, 11 Oct 1993 11:10:42 +0100 Sender: Guido.van.Rossum@cwi.nl > In an exception handler, how does one find out what the exception being > handled was? Is it possible? I'd like to write something like: > > try: > foo() > except: > something(e) > > where e is the specific exception. Ah, that's an easy one, though I agree that the docs for this aren't where you have probably been looking for them. The module sys defines three variables: exc_type, exc_value and exc_traceback, which are set to the current exception when an except clause is entered. Note the distinction with the three similar variables last_type, ... which are only set when the exception isn't handled and the interpreter prints a stack trace. (This done so you can then import the debugger and use it for post-mortem browsing. Also see the -i option to the interpreter.) --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Tue, 12 Oct 1993 10:34:50 +0100 Replied: "Bill Janssen <janssen@parc.xerox.com> python-list" Received: from alpha.Xerox.COM by charon.cwi.nl with SMTP id AA25335 (5.65b/3.10/CWI-Amsterdam); Tue, 12 Oct 1993 00:20:02 +0100 Received: from holmes.parc.xerox.com ([13.1.100.162]) by alpha.xerox.com with SMTP id <11747>; Mon, 11 Oct 1993 16:19:42 PDT Received: by holmes.parc.xerox.com id <16134>; Mon, 11 Oct 1993 16:19:31 -0700 From: Bill Janssen <janssen@parc.xerox.com> To: python-list@cwi.nl Subject: Some python comments/questions Message-Id: <93Oct11.161931pdt.16134@holmes.parc.xerox.com> Date: Mon, 11 Oct 1993 16:19:20 PDT I'm happier with python than with any scripting/extension language I've ever tried... but I have a few comments/questions: 1) I'm addicted to the C syntax of ?:, as in foo ((a < b) ? c : d); Is there some equivalent in python? 2) It would often be useful if there was some way to create function objects without binding them to some name. You can do it with something like def makefuncobj (): def tmp (x, y, z): return (x + y * z) return(tmp) a = makefuncobj() but you need to define a new makefuncobj for every function you wish to dynamically create, which takes some of the dynamism out of it :-). I'd like to be able to have some expression whihc evaluates to a function object without binding any names, perhaps something like a = def *(x, y, z): return x + y * z; You could almost do it with exec(), I'd think, except that exec() doesn't return its value. Are multi-line expressions even allowed? 3) Are exceptions implemented in such a way as to be thread-safe? You speak in the EXTENDING document of a global variable that is bound... 4) I'd like to extend python to speak ILU, the distributed interface system we're developing here. My thought is to add the ILU parser and runtime kernel to the interpreter core, and then use it thusly: A new call, ilu.load(<interface-file-name>), will use the ILU parser to read and parse the file describing one or more interfaces; the parse tree will then be interpreted in C. In C, a new module will be defined for every interface defined in the file; a new object type will be defined for every object type defined in every interface; a new method object will be generated for every method of every new object type; every method will look something like def m(self, *args) return(ilu.call (self, <x>, args)) where <x> is a description of method m's signature. Note that there will be no corresponding method in C for these newly defined methods. OK, so defining new modules at the C level isn't hard. Event objects aren't bad. But I don't see how to define new methods or function objects without real C functions to bind them to. 5) It's too bad that development on STDWIN is discontinued. We use both Macs and UNIX here, and having a portable UI interface is very nice. Not to mention that python with Motif is 3 MB, without Motif it's 1 MB. Bill Replied: Tue, 12 Oct 1993 09:51:52 +0100 Replied: "Bill Janssen <janssen@parc.xerox.com> python-list" Received: from alpha.Xerox.COM by charon.cwi.nl with SMTP id AA26707 (5.65b/3.10/CWI-Amsterdam); Tue, 12 Oct 1993 02:27:07 +0100 Received: from holmes.parc.xerox.com ([13.1.100.162]) by alpha.xerox.com with SMTP id <11799>; Mon, 11 Oct 1993 18:26:51 PDT Received: by holmes.parc.xerox.com id <16134>; Mon, 11 Oct 1993 18:26:44 -0700 From: Bill Janssen <janssen@parc.xerox.com> To: python-list@cwi.nl Subject: bug in stdwinmodule.c Message-Id: <93Oct11.182644pdt.16134@holmes.parc.xerox.com> Date: Mon, 11 Oct 1993 18:26:32 PDT The event WE_SIZE does not have detail (width, height), as promised in lib/stdwinevents.py. Bill Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA03081 (5.65b/3.10/CWI-Amsterdam); Tue, 12 Oct 1993 09:51:53 +0100 Received: by voorn.cwi.nl with SMTP id AA28934 (5.65b/3.8/CWI-Amsterdam); Tue, 12 Oct 1993 09:51:52 +0100 Message-Id: <9310120851.AA28934=guido@voorn.cwi.nl> To: Bill Janssen <janssen@parc.xerox.com> Cc: python-list@cwi.nl Subject: Re: bug in stdwinmodule.c In-Reply-To: Your message of "Mon, 11 Oct 1993 18:26:32 MDT." <93Oct11.182644pdt.16134@holmes.parc.xerox.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Tue, 12 Oct 1993 09:51:52 +0100 Sender: Guido.van.Rossum@cwi.nl > The event WE_SIZE does not have detail (width, height), as > promised in lib/stdwinevents.py. That comment in lib/stdwinevents.py seems to be in error. The C interface does not return the new width/height (you're supposed to call wgetwinsize(); window.getwinsize() in Python). --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA04073 (5.65b/3.10/CWI-Amsterdam); Tue, 12 Oct 1993 10:34:50 +0100 Received: by voorn.cwi.nl with SMTP id AA29050 (5.65b/3.8/CWI-Amsterdam); Tue, 12 Oct 1993 10:34:51 +0100 Message-Id: <9310120934.AA29050=guido@voorn.cwi.nl> To: Bill Janssen <janssen@parc.xerox.com> Cc: python-list@cwi.nl Subject: Re: Some python comments/questions In-Reply-To: Your message of "Mon, 11 Oct 1993 16:19:20 MDT." <93Oct11.161931pdt.16134@holmes.parc.xerox.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Tue, 12 Oct 1993 10:34:50 +0100 Sender: Guido.van.Rossum@cwi.nl > I'm happier with python than with any scripting/extension language > I've ever tried...but I have a few comments/questions: Flatterer! > 1) I'm addicted to the C syntax of ?:, as in > > foo ((a < b) ? c : d); > > Is there some equivalent in python? Not directly. (I guess when designing Python I was copying parts of the design goals of ABC, which wanted to get rid of C's 13 levels of operator priorities...) Sometimes you can get away with "a and b" which returns either the value of a or the value of b, not 0 or 1 as in C -- Python's "a and b" is like "a ? a : b" except a is evaluated only once. Given that Python uses keywords 'and' and 'or', the '?:' construct would probably have to be written with keywords as well -- can't think of any obvious ones though. (Functional notation is out since built-in functions always evaluate all their arguments.) But I must say that I've never missed it and in fact you're the first one who asks for it... > 2) It would often be useful if there was some way to create function > objects without binding them to some name. You can do it with > something like > > def makefuncobj (): > def tmp (x, y, z): > return (x + y * z) > return(tmp) > > a = makefuncobj() > > but you need to define a new makefuncobj for every function you > wish to dynamically create, which takes some of the dynamism > out of it :-). I'd like to be able to have some expression whihc > evaluates to a function object without binding any names, perhaps > something like > > a = def *(x, y, z): > return x + y * z; > > You could almost do it with exec(), I'd think, except that exec() > doesn't return its value. Are multi-line expressions even allowed? Multi-line expressions like this would require a major redesign of the expression syntax. I guess you're stuck with what you've got. However, I don't see the reason why you don't want to bind any names. I would personally write your first example like this: def tmp(x, y, z): return x + y * z a = tmp Note that if you execute this code many times (say in a loop) the 'def' statement will create a new function object each time. (In fact the semantics of a 'def' statement are assignment to the defined function name.) But maybe you can give an example where this isn't sufficient? > 3) Are exceptions implemented in such a way as to be thread-safe? > You speak in the EXTENDING document of a global variable that is > bound... I don't think they currently are. This is one of the areas that needs fixing up when more machines get usable thread implementations (currently the SGI is the only one where this really works). It shouldn't be too hard to fix though since most of the interface already uses function, the global variables are static. > 4) I'd like to extend python to speak ILU, the distributed interface > system we're developing here. My thought is to add the ILU parser > and runtime kernel to the interpreter core, and then use it thusly: > > A new call, ilu.load(<interface-file-name>), will use the ILU parser > to read and parse the file describing one or more interfaces; the > parse tree will then be interpreted in C. In C, a new module will be > defined for every interface defined in the file; a new object type > will be defined for every object type defined in every interface; a > new method object will be generated for every method of every new > object type; every method will look something like > > def m(self, *args) > return(ilu.call (self, <x>, args)) > > where <x> is a description of method m's signature. Note that there > will be no corresponding method in C for these newly defined methods. > > OK, so defining new modules at the C level isn't hard. Event objects > aren't bad. But I don't see how to define new methods or function > objects without real C functions to bind them to. This sounds remarkably similar to what the 'amoeba' module does, for RPC in the (now almost forgotten?) distributed operating system by that name (most of the code is in files whose name starts with 'sc' though). There the parsing is done outside python and loading an interface will read the result of the parsing from a file, but that's not an essential difference. All methods are bound to the same C function, the "universal RPC marshalling method", which also gets a pointer to the result of the parsing. The latter is actually a tiny program for a virtual machine that does the (un)marshalling of arguments and results. Since the structure of the C code generated by RPC generators for marshalling functions is usually pretty regular, it doesn't require too much work to write such a "generic marshaller", especially since the arguments are available as a Python tuple and not in some machine-dependent format on the C stack. > 5) It's too bad that development on STDWIN is discontinued. We use > both Macs and UNIX here, and having a portable UI interface is very > nice. Not to mention that python with Motif is 3 MB, without Motif > it's 1 MB. Well, I'm looking for sponsors or other outside help... If someone would do a MS Windows port, STDWIN might become more popular, and then I might be convinced that it's worthwile to do some more development; STDWIN especially needs a better way to handle dialogs with buttons and text fields etc. Any volunteers? (Personally, I find hacking Python much more fun than hacking STDWIN :-) --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Forwarded: Tue, 12 Oct 1993 16:10:44 +0100 Forwarded: "<andrewn@eaps.sussex.ac.uk>,<bevan@cs.man.ac.uk>,<peter@robots.oxford.ac.uk>,<python-users@camscan.co.uk>,<Timothy.Roscoe@cl.cam.ac.uk>,<ckh@cl.cam.ac.uk " Forwarded: Tue, 12 Oct 1993 15:18:46 +0100 Forwarded: "<ckh@cl.cam.ac.uk>,<Timothy.Roscoe@cl.cam.ac.uk>,<python-users@camscan.co.uk>,<peter@robots.oxford.ac.uk>,<bevan@cs.man.ac.uk>,<andrewn@eaps.sussex.ac.uk " Forwarded: Tue, 12 Oct 1993 15:10:19 +0100 Forwarded: ""andrew d. nimmo" <andrewn@eaps.sussex.ac.uk>,"stephen j. bevan" <bevan@cs.man.ac.uk>,peter ho <peter@robots.oxford.ac.uk>,python-users@camscan.co.uk,Timothy Roscoe <Timothy.Roscoe@cl.cam.ac.uk>,Chris Hadley <ckh@cl.cam.ac.uk> " Resent: Tue, 12 Oct 1993 15:08:23 +0100 Resent: ""andrew d. nimmo" <andrewn@eaps.sussex.ac.uk>,"stephen j. bevan" <bevan@cs.m Resent: an.ac.uk>,peter ho <peter@robots.oxford.ac.uk>,python-users@camscan.co.uk,Timoth Resent: y Roscoe <Timothy.Roscoe@cl.cam.ac.uk>,Chris Hadley <ckh@cl.cam.ac.uk> " Replied: Tue, 12 Oct 1993 14:45:56 +0100 Replied: ""Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Bill Janssen <janssen@parc.xerox.com>, python-list@cwi.nl" Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA09632 (5.65b/3.10/CWI-Amsterdam); Tue, 12 Oct 1993 14:16:39 +0100 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa01771; 12 Oct 93 9:16 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA14773; Tue, 12 Oct 1993 09:16:14 -0400 Date: Tue, 12 Oct 1993 09:16:14 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199310121316.AA14773@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: Bill Janssen <janssen@parc.xerox.com> Subject: Re: Some python comments/questions [ #1: "?:" equivalent ] Cc: python-list@cwi.nl On Oct 11, 16:19, Bill Janssen wrote: > > I'm happier with python than with any scripting/extension language > I've ever tried... but I have a few comments/questions: > > 1) I'm addicted to the C syntax of ?:, as in > > foo ((a < b) ? c : d); > > Is there some equivalent in python? > Having played around with trying to use and/or to force python into a more C-like expression oriented pattern lately in my Obfuscated Python posts, this comes to mind: >>> ((( 1 < 2 ) and ( 'Less Than' ) or ( 'Not Less Than' ))) 'Less Than' >>> ((( 3 < 2 ) and ( 'Less Than' ) or ( 'Not Less Than' ))) 'Not Less Than' But I think the following is more python-ish: >>> ( 'Not Less Than', 'Less Than' )[ ( 1 < 2 ) ] 'Less Than' >>> ( 'Not Less Than', 'Less Than' )[ ( 3 < 2 ) ] 'Not Less Than' i.e. using the boolean False = 0 / True = 1 to map into a tuple index. BUT: since None and empty sequences are also false and all others true, there is no guarantee that this will work for all tests. Predictions: Tim will love it! Guido *may* feel a bit ill at our continual efforts to make python look like C ! - sdm Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA10274 (5.65b/3.10/CWI-Amsterdam); Tue, 12 Oct 1993 14:45:57 +0100 Received: by voorn.cwi.nl with SMTP id AA00169 (5.65b/3.8/CWI-Amsterdam); Tue, 12 Oct 1993 14:45:57 +0100 Message-Id: <9310121345.AA00169=guido@voorn.cwi.nl> To: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Cc: Bill Janssen <janssen@parc.xerox.com>, python-list@cwi.nl Subject: Re: Some python comments/questions [ #1: "?:" equivalent ] In-Reply-To: Your message of "Tue, 12 Oct 1993 09:16:14 MET." <199310121316.AA14773@elvis.med.Virginia.EDU> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Tue, 12 Oct 1993 14:45:56 +0100 Sender: Guido.van.Rossum@cwi.nl > >>> ((( 1 < 2 ) and ( 'Less Than' ) or ( 'Not Less Than' ))) > 'Less Than' > >>> ((( 3 < 2 ) and ( 'Less Than' ) or ( 'Not Less Than' ))) > 'Not Less Than' BUT, if you use this with generalized expressions instead of literals, it may fail: if you evaluate "x and y or z" with x true and y false (e.g. an empty list), result will still be z, unlike for x?y:z, where it will be y. > >>> ( 'Not Less Than', 'Less Than' )[ ( 1 < 2 ) ] > 'Less Than' > >>> ( 'Not Less Than', 'Less Than' )[ ( 3 < 2 ) ] > 'Not Less Than' This of course has the disadvantage that it always evaluates both branches of the if-then-else. > BUT: since None and empty sequences are also > false and all others true, there is no guarantee that this > will work for all tests. To convert any Boolean x into 0 or 1: "x and 1 or 0". Anybody come up with a reasonable alternative syntax for x?y:z...? --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> PS sometimes I get mail suggesting a switch/case statement. Do people generally miss this? Received: from mailgate.ericsson.se by charon.cwi.nl with SMTP id AA12087 (5.65b/3.10/CWI-Amsterdam); Tue, 12 Oct 1993 15:52:22 +0100 Received: from eua.ericsson.se by mailgate.ericsson.se (4.1/SMI-4.1-MAILGATE1.14) id AA23986; Tue, 12 Oct 93 15:52:19 +0100 Received: from ms.eua.ericsson.se by eua.ericsson.se (4.1/EUA-2.1) id AA02615; Tue, 12 Oct 93 15:52:18 +0100 Received: from euas09c18.eua.ericsson.se by ms.eua.ericsson.se (4.1/MS-2.1) id AA03466; Tue, 12 Oct 93 15:52:16 +0100 From: Mats.Lidell@eua.ericsson.se (Mats Lidell) Received: by euas09c18.eua.ericsson.se (4.1/client-1.3) id AA18949; Tue, 12 Oct 93 15:52:15 +0100 Date: Tue, 12 Oct 93 15:52:15 +0100 Message-Id: <9310121452.AA18949@euas09c18.eua.ericsson.se> To: Guido.van.Rossum@cwi.nl Cc: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu>, Bill Janssen <janssen@parc.xerox.com>, python-list@cwi.nl Subject: Re: Some python comments/questions [ #1: "?:" equivalent ] In-Reply-To: <9310121345.AA00169=guido@voorn.cwi.nl> References: <199310121316.AA14773@elvis.med.Virginia.EDU> <9310121345.AA00169=guido@voorn.cwi.nl> Comments: Hyperbole mail buttons accepted, v3.09. >>>>> Guido recently wrote: Guido> Anybody come up with a reasonable alternative syntax for Guido> x?y:z...? ... will be shot :-) Please don't obscure the language with these type of C things! Keep it clean. If python wanted to be C we would have called it perl! By the way, I miss some things from Modula and Eiffel ... ;-) %% Mats Replied: Tue, 12 Oct 1993 17:34:03 +0100 Replied: "Quentin Stafford-Fraser <Fraser@europarc.xerox.com> lutz@xvt.com (Mark Lutz), python-list" Received: from alpha.Xerox.COM by charon.cwi.nl with SMTP id AA13356 (5.65b/3.10/CWI-Amsterdam); Tue, 12 Oct 1993 16:31:06 +0100 Received: from eros.EuroPARC.Xerox.COM ([13.1.252.143]) by alpha.xerox.com with SMTP id <11970>; Tue, 12 Oct 1993 08:30:34 PDT Received: by eros.EuroPARC.Xerox.COM (5.65c/IDA-1.2.9) id AA22375; Tue, 12 Oct 1993 16:29:13 +0100 Date: Tue, 12 Oct 1993 08:29:13 PDT From: Quentin Stafford-Fraser <Fraser@europarc.xerox.com> Message-Id: <199310121529.AA22375@eros.EuroPARC.Xerox.COM> To: lutz@xvt.com (Mark Lutz) Cc: guido@cwi.nl In-Reply-To: lutz@xvt.com's message of Mon, 11 Oct 1993 16:26:10 GMT Subject: Re: Has anyone done a tk addition to perl? Hi Mark - > This stuff probably doesn't belong here [comp.lang.tcl]; is there any > interest in starting a comp.lang.python news group? I think it would be great, if for no other reason than making python more visible to the world, but I don't know enough about the protocol for creating groups. I suspect python doesn't yet have a large enough user community to get the required votes. Guido - any thoughts? This must have come up before, but if so I missed it. How many people are there on the mailing list? Quentin Received: from hopscotch.ksr.com by charon.cwi.nl with SMTP id AA13722 (5.65b/3.10/CWI-Amsterdam); Tue, 12 Oct 1993 16:42:47 +0100 Received: from ksr.com (frankenstein.ksr.com) by hopscotch.ksr.com with SMTP id AA05667; Tue, 12 Oct 1993 11:42:16 -0400 Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA24457; Tue, 12 Oct 93 11:42:44 EDT Received: by kaos.ksr.com (4.1/KSR-2.0) id AA02396; Tue, 12 Oct 93 11:42:42 EDT Message-Id: <9310121542.AA02396@kaos.ksr.com> To: Guido.van.Rossum@cwi.nl, sdm7g@elvis.med.virginia.edu, janssen@parc.xerox.com Subject: Re: Some python comments/questions [ #1: "?:" equivalent ] Cc: python-list@cwi.nl Date: Tue, 12 Oct 93 11:42:39 -0400 From: Tim Peters <tim@ksr.com> Always happy to raise the level of illness <wink>: combining the sick ideas presented so far, I believe a faithful translation of "a?b:c" is: (a and [b] or [c])[0] as in: >>> (1<2 and 0 or 4) # oops 4 >>> (1<2 and [0] or [4])[0] # bliss 0 >>> That is, we hide b and c inside singleton lists; then [b] and [c] are always "true", regardless of the values of b and c; so short-circuiting reliably returns the desired one of "[b]" and "[c]"; and strip the value out of the list at the end. This also worms around the multiple-evaluation problem. Of course I'd rather have my eyes eaten out by a horde of tiny wasps than actually _use_ this idiom (or-- worse --be forced to read someone else's code that used it), but it just goes to show once again that Guido anticipated all possible complaints years before we thought of them <wink>. Seriously, Python isn't an "expression" language (I'd call it a "statement" language, hoping the intuitive distinction is clear), so things "like this" don't seem (to me) to fit well in it: I stopped missing "?:" early on (perhaps because min and max are built in!), and by now am 95% reconciled to assignment being a statement instead of an expression. If "?:" absolutely had to be added to Python, I expect that "if a then b else c" would be an OK way to spell it. on-the-other-hand-a-"case"-statement-is-a-natural!-ly y'rs - tim Tim Peters tim@ksr.com not speaking for Kendall Square Research Corp Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA15217 (5.65b/3.10/CWI-Amsterdam); Tue, 12 Oct 1993 17:34:05 +0100 Received: by voorn.cwi.nl with SMTP id AA01072 (5.65b/3.8/CWI-Amsterdam); Tue, 12 Oct 1993 17:34:03 +0100 Message-Id: <9310121634.AA01072=guido@voorn.cwi.nl> To: Quentin Stafford-Fraser <Fraser@europarc.xerox.com> Cc: lutz@xvt.com (Mark Lutz), python-list@cwi.nl Subject: Re: Has anyone done a tk addition to perl? In-Reply-To: Your message of "Tue, 12 Oct 1993 08:29:13 MDT." <199310121529.AA22375@eros.EuroPARC.Xerox.COM> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Tue, 12 Oct 1993 17:34:03 +0100 Sender: Guido.van.Rossum@cwi.nl (Python-list members: I got a mail from Quentin suggesting that a comp.lang.python group be created. Here's my reply.) The Python mailing list currently has just over 100 members, and is growing slowly (but surely), so I don't think there is yet a compelling reason for creating a newsgroup. My personal hope is that posting 1.0 to comp.sources.unix (or .misc) will boost the number of users by a large factor and then we'll have to reconsider this. I wish I could do more on publicity, e.g. put papers in conferences (USENIX being an obvious candidate) or write a book about Python, but the grim reality is that my research topics for the next few years are something completely different so it isn't likely that my employer will pay for my time writing a book about Python, nor for traveling to a conference to talk about it. I also have some vague ideas to promote Python as a multimedia prototyping language (since that what it is being used for most successfully here at CWI), but this will again depend on finding the spare time to complete, unify, generalize and document the stuff we are currently using internally (some, but not all, of which is part of the Python release). Anybody else? --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> To: Quentin Stafford-Fraser <Fraser@europarc.xerox.com> cc: lutz@xvt.com (Mark Lutz), python-list Subject: Re: Has anyone done a tk addition to perl? In-reply-to: Your message of "Tue, 12 Oct 1993 08:29:13 MDT." <199310121529.AA22375@eros.EuroPARC.Xerox.COM> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Tue, 12 Oct 1993 17:34:03 +0100 Sender: guido (Python-list members: I got a mail from Quentin suggesting that a comp.lang.python group be created. Here's my reply.) The Python mailing list currently has just over 100 members, and is growing slowly (but surely), so I don't think there is yet a compelling reason for creating a newsgroup. My personal hope is that posting 1.0 to comp.sources.unix (or .misc) will boost the number of users by a large factor and then we'll have to reconsider this. I wish I could do more on publicity, e.g. put papers in conferences (USENIX being an obvious candidate) or write a book about Python, but the grim reality is that my research topics for the next few years are something completely different so it isn't likely that my employer will pay for my time writing a book about Python, nor for traveling to a conference to talk about it. I also have some vague ideas to promote Python as a multimedia prototyping language (since that what it is being used for most successfully here at CWI), but this will again depend on finding the spare time to complete, unify, generalize and document the stuff we are currently using internally (some, but not all, of which is part of the Python release). Anybody else? --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Wed, 13 Oct 1993 10:28:45 +0100 Replied: "Mark Lutz <lutz@xvt.com> janssen@parc.xerox.com (Bill Janssen), python-list@cwi.nl" Received: from csn.org by charon.cwi.nl with SMTP id AA18659 (5.65b/3.10/CWI-Amsterdam); Tue, 12 Oct 1993 20:27:38 +0100 Received: by csn.org with UUCP id AA28243 (5.65c/IDA-1.4.4 for python-list@cwi.nl); Tue, 12 Oct 1993 13:26:38 -0600 Received: by zeus.xvt.com id AA18144 (5.65c/IDA-1.4.4); Tue, 12 Oct 1993 11:41:37 -0600 From: Mark Lutz <lutz@xvt.com> Message-Id: <199310121741.AA18144@zeus.xvt.com> Subject: Re: Some python comments/questions To: janssen@parc.xerox.com (Bill Janssen) Date: Tue, 12 Oct 93 11:41:36 MDT Cc: python-list@cwi.nl In-Reply-To: <93Oct11.161931pdt.16134@holmes.parc.xerox.com>; from "Bill Janssen" at Oct 11, 93 4:19 pm You write: > 2) It would often be useful if there was some way to create function > objects without binding them to some name. You can do it with > something like > > def makefuncobj (): > def tmp (x, y, z): > return (x + y * z) > return(tmp) > > a = makefuncobj() > > but you need to define a new makefuncobj for every function you > wish to dynamically create, which takes some of the dynamism > out of it :-). I'd like to be able to have some expression whihc > evaluates to a function object without binding any names, perhaps > something like > > a = def *(x, y, z): > return x + y * z; > > You could almost do it with exec(), I'd think, except that exec() > doesn't return its value. Are multi-line expressions even allowed? If I understand your problem correctly, you can solve it with exec() and strings. Things get a little tricky with multi-line function bodies (since you need to remember to add '\n' and indentation in the strings) , but it works. Consider the following 2 functions: def genfunc(args, expr): exec('def f(' + args + '): return ' + expr) return eval('f') def genproc(args, body): exec('def f(' + args + '):' + body + '\n') return eval('f') genfunc() will create and return a new function that just returns the value of an expression applied to arguments. For example: x = genfunc('x, y', '(x * y) - (x + y)') x(3, 4) -> 5 genproc() will build a function with a procedure body you pass in, which can contain references to the symbols in the argument string: x = genproc('i, j', '\n for x in range(i,j): print x,\n print') x(0,10) will print 0 1 2 ...9 and a new-line. Note that "f" in both functions is a local variable, so you're not really creating new symbols. You need to "return eval('f')", instead of "return f" in my python version, since "f" is not known to be a local variable statically (you could also do an initial "f = None", to avoid having to "eval('f')"). You could also use the generated function directly, but it's not too useful: genfunc('x, y, z', 'x * y * x')(2, 4, 6) -> 48 Here's a test program that illustrates a bit more: def test(): a, b = 3, 10 x = genfunc('x, y', 'x * 2 + y') print x(2, 5) # 9 print x(a, b) # 16 y = genfunc('x, y, z', 'x * y * z') print y(1,2,3) # 6 print y(a, b, 5) # 150 print x(10, a) # 23 z = genfunc('f, x', 'f(x, x) * 2') print z(x, b) # 60 global msg; msg = 'it works.' a = genproc('', 'print msg * 3') a() # 'it works.' * 3 genproc('', 'print msg * 4')() # 'it works.' * 4 a = genproc('x, y', '\n for i in range(x,y): print i,\n print') a(0,10) # 0..9 a(z(x,2), y(1,3,4)+5) # 12..16 b = genproc('f, m', 'f(0,10); print m') b(a, 'all done.') # 0..9, 'all done.' c = genproc('l, r', 'l; exec(r)') c(a(0,10), 'print \'all done.\'') # ditto d = genproc('l, r', 'exec(l); exec(r)') d('for i in range(0,10): print i,', 'print \'all done.\'') Mark Lutz lutz@xvt.com Received: from hopscotch.ksr.com by charon.cwi.nl with SMTP id AA17877 (5.65b/3.10/CWI-Amsterdam); Tue, 12 Oct 1993 19:43:48 +0100 Received: from ksr.com (frankenstein.ksr.com) by hopscotch.ksr.com with SMTP id AA07820; Tue, 12 Oct 1993 14:43:27 -0400 Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA26100; Tue, 12 Oct 93 14:43:57 EDT Received: by kaos.ksr.com (4.1/KSR-2.0) id AA10884; Tue, 12 Oct 93 14:43:55 EDT Message-Id: <9310121843.AA10884@kaos.ksr.com> To: janssen@parc.xerox.com Subject: Anonymous functions (was Re: Some python comments/questions) Cc: python-list@cwi.nl Date: Tue, 12 Oct 93 14:43:54 -0400 From: Tim Peters <tim@ksr.com> > 2) It would often be useful if there was some way to create function > objects without binding them to some name. You can do it with > something like > > def makefuncobj (): > def tmp (x, y, z): > return (x + y * z) > return(tmp) > > a = makefuncobj() > > but you need to define a new makefuncobj for every function you > wish to dynamically create, which takes some of the dynamism > out of it :-). ... You might find the following handy, for creating simple "one-liner" functions on the fly: from string import find def func( f ): i = find( f, ':' ) if i < 0: raise ValueError, 'need colon in function string ' + `f` args, body = f[:i], f[i+1:] f = 'def f(' + args + '): return ' + body bad = 1 # guilty until proven innocent try: exec( f ) # creates local func 'f' bad = 0 finally: if bad: print 'Error in func: couldn\'t exec ' + `f` return f This takes a string of the form [arglist] ':' expression as its argument, and returns the function defined by 'def f(' arglist '): return ' expression The name 'f' is local to the invocation of 'func', so effectively vanishes when 'func' returns (the binding of the _name_ 'f' to the function object vanishes, but the function object itself does not); so from the point of view of the caller, the function returned by 'func' is anonymous (cannot interfere with name bindings in the caller, or indeed even be invoked by name). For example, given function def map( f, x ): y = [] for e in x: y.append( f(e) ) return y we have >>> map( func('x: x*x'), range(8) ) [0, 1, 4, 9, 16, 25, 36, 49] >>> Or >>> flist = map( func, ['x:x+x', 'y:y*y', 'z:42'] ) >>> for f in flist: ... print f(3) ... 6 9 42 >>> I often find 'func' to be handy, in conjunction with LISPish functions like 'map', when doing interactive data crunching. > You could almost do it with exec(), I'd think, except that exec() > doesn't return its value. Right, that's why the exec is packaged inside a function here. > Are multi-line expressions even allowed? The context ("allowed" where?) wasn't clear to me. exec will crunch any legit Python program text, and it's certainly possible to generalize 'func' to allow creating anonymous functions built out of arbitrary Python code. But note that representing complex functions as strings gets clumsy, because you have to get the newlines, and the right amount of leading indentation, in the right places (or, define an un-Python-like string representation, and program a fancier 'func' to translate that into legit Python before handing it to 'exec'). the-function-that-is-named-is-not-the-true-function-ly y'rs - tim Tim Peters tim@ksr.com not speaking for Kendall Square Research Corp Replied: Wed, 13 Oct 1993 10:36:58 +0100 Replied: "Mark Lutz <lutz@xvt.com> " Received: from csn.org by charon.cwi.nl with SMTP id AA21810 (5.65b/3.10/CWI-Amsterdam); Tue, 12 Oct 1993 23:42:25 +0100 Received: by csn.org with UUCP id AA20093 (5.65c/IDA-1.4.4 for python-list@cwi.nl); Tue, 12 Oct 1993 16:15:58 -0600 Received: by zeus.xvt.com id AA22425 (5.65c/IDA-1.4.4); Tue, 12 Oct 1993 15:13:31 -0600 From: Mark Lutz <lutz@xvt.com> Message-Id: <199310122113.AA22425@zeus.xvt.com> Subject: Re: Some python comments/questions (correction) To: janssen@parc.xerox.com (Bill Janssen) Date: Tue, 12 Oct 93 15:13:31 MDT Cc: python-list@cwi.nl In-Reply-To: <93Oct11.161931pdt.16134@holmes.parc.xerox.com>; from "Bill Janssen" at Oct 11, 93 4:19 pm A minor correction; I wrote (much too fast...): > genfunc('x, y, z', 'x * y * x')(2, 4, 6) -> 48 Of course, it should read: genfunc('x, y, z', 'x * y * z')(2, 4, 6) -> 48 Sorry if this caused confusion. Another poster also points out that anonymous functions _are_ useful in Lisp-like mapping functions. And now for something completely different... 1) What are the major differences between python 0.9.8 to 0.9.9? [I'd ftp the new system , but I don't have convenient ftp access at the moment.] 2) Is there any date in mind for release 1.0 to come out? Again, what might that introduce? Thanks, lutz@xvt.com Replied: Wed, 13 Oct 1993 09:43:06 +0100 Replied: "python-list@cwi.nl " Received: from boring.cwi.nl by charon.cwi.nl with SMTP id AA23109 (5.65b/3.10/CWI-Amsterdam); Wed, 13 Oct 1993 00:27:21 +0100 Received: by boring.cwi.nl id AA05848 (4.1/2.10/CWI-Amsterdam); Wed, 13 Oct 93 00:27:21 +0100 Date: Wed, 13 Oct 93 00:27:21 +0100 From: Dik.Winter@cwi.nl Message-Id: <9310122327.AA05848.dik@boring.cwi.nl> To: python-list@cwi.nl Subject: Re: Some python comments/questions (correction) > 1) What are the major differences between python 0.9.8 to 0.9.9? > [I'd ftp the new system , but I don't have convenient ftp > access at the moment.] > 2) Is there any date in mind for release 1.0 to come out? > Again, what might that introduce? Trust Guido to come up with 0.9.9.1 next ;-). Replied: Wed, 13 Oct 1993 10:57:41 +0100 Replied: "Bill Janssen <janssen@parc.xerox.com> python-list" Received: from alpha.Xerox.COM by charon.cwi.nl with SMTP id AA24506 (5.65b/3.10/CWI-Amsterdam); Wed, 13 Oct 1993 02:03:43 +0100 Received: from holmes.parc.xerox.com ([13.1.100.162]) by alpha.xerox.com with SMTP id <11970>; Tue, 12 Oct 1993 18:03:12 PDT Received: by holmes.parc.xerox.com id <16134>; Tue, 12 Oct 1993 18:03:03 -0700 Received: from Messages.7.15.N.CUILIB.3.45.SNAP.NOT.LINKED.holmes.parc.xerox.com.sun4.41 via MS.5.6.holmes.parc.xerox.com.sun4_41; Tue, 12 Oct 1993 18:02:56 -0700 (PDT) Message-Id: <8gipD08B0KGWFDkAp_@holmes.parc.xerox.com> Date: Tue, 12 Oct 1993 18:02:56 PDT Sender: Bill Janssen <janssen@parc.xerox.com> From: Bill Janssen <janssen@parc.xerox.com> To: python-list@cwi.nl Subject: Python and UI Another tack might be to drop the use of STDWIN, and substitute something else that's already been ported. SUIT comes to mind, for example. A system that might better match Python's perspicuity, though, is something more like Joel Bartlett's EZD (ftp://gatekeeper.dec.com/pub/DEC/ezd/). Bill Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA02105 (5.65b/3.11/CWI-Amsterdam); Wed, 13 Oct 1993 09:43:05 +0100 Received: by voorn.cwi.nl with SMTP id AA02694 (5.65b/3.8/CWI-Amsterdam); Wed, 13 Oct 1993 09:43:06 +0100 Message-Id: <9310130843.AA02694=guido@voorn.cwi.nl> To: python-list@cwi.nl Subject: Re: Some python comments/questions (correction) In-Reply-To: Your message of "Wed, 13 Oct 1993 00:27:21 MET." <9310122327.AA05848.dik@boring.cwi.nl> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Wed, 13 Oct 1993 09:43:06 +0100 Sender: Guido.van.Rossum@cwi.nl > > 2) Is there any date in mind for release 1.0 to come out? > > Again, what might that introduce? > > Trust Guido to come up with 0.9.9.1 next ;-). Actually I'm firmly committed to post it to comp.sources.unix (or .misc? which would be better?) before the end of 1993. Of course it may be almost identical to 0.9.9 except for the name space changes... --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> To: python-list@cwi.nl Subject: Re: Some python comments/questions (correction) In-reply-to: Your message of "Wed, 13 Oct 1993 00:27:21 MET." <9310122327.AA05848.dik@boring.cwi.nl> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Wed, 13 Oct 1993 09:43:06 +0100 Sender: guido > > 2) Is there any date in mind for release 1.0 to come out? > > Again, what might that introduce? > > Trust Guido to come up with 0.9.9.1 next ;-). Actually I'm firmly committed to post it to comp.sources.unix (or .misc? which would be better?) before the end of 1993. Of course it may be almost identical to 0.9.9 except for the name space changes... --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Wed, 13 Oct 1993 11:07:03 +0100 Replied: "Quentin Stafford-Fraser <Fraser@europarc.xerox.com> python-list@cwi.nl" Received: from alpha.Xerox.COM by charon.cwi.nl with SMTP id AA00984 (5.65b/3.11/CWI-Amsterdam); Wed, 13 Oct 1993 10:25:26 +0100 Received: from eros.EuroPARC.Xerox.COM ([13.1.252.143]) by alpha.xerox.com with SMTP id <12073>; Wed, 13 Oct 1993 02:25:09 PDT Received: by eros.EuroPARC.Xerox.COM with SMTP (5.65c/IDA-1.2.9) id AA28934; Wed, 13 Oct 1993 10:24:18 +0100 Message-Id: <199310130924.AA28934@eros.EuroPARC.Xerox.COM> To: python-list@cwi.nl Subject: Re: Some python comments/questions (correction) In-Reply-To: Your message of "Wed, 13 Oct 93 01:43:06 PDT." <9310130843.AA02694=guido@voorn.cwi.nl> Date: Wed, 13 Oct 1993 02:24:17 PDT From: Quentin Stafford-Fraser <Fraser@europarc.xerox.com> > Actually I'm firmly committed to post it to comp.sources.unix (or > .misc? which would be better?) before the end of 1993. Of course it > may be almost identical to 0.9.9 except for the name space changes... Good - I'm thinking of doing a Modula-3 interface, but I'm waiting for the name changes... I have to say that I don't think the 'primes' program included in the BLURB document is a good example of Python's clarity and ease-of-use. We need a clear bit of sample code that makes people say "Hey, this is worth downloading" when it appears on comp.sources. Anybody like to volunteer some? Quentin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Quentin Stafford-Fraser Tel: +44 223 341521 Rank Xerox EuroPARC, Fax: +44 223 341510 61 Regent Street, Home: +44 223 324451 Cambridge, CB2 1AB United Kingdom Fraser@europarc.xerox.com You can retrieve my pgp public key using "finger qs101@osprey.cl.cam.ac.uk" Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA01023 (5.65b/3.11/CWI-Amsterdam); Wed, 13 Oct 1993 10:28:47 +0100 Received: by voorn.cwi.nl with SMTP id AA02952 (5.65b/3.8/CWI-Amsterdam); Wed, 13 Oct 1993 10:28:46 +0100 Message-Id: <9310130928.AA02952=guido@voorn.cwi.nl> To: Mark Lutz <lutz@xvt.com> Cc: janssen@parc.xerox.com (Bill Janssen), python-list@cwi.nl Subject: Re: Some python comments/questions In-Reply-To: Your message of "Tue, 12 Oct 1993 11:41:36 MDT." <199310121741.AA18144@zeus.xvt.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Wed, 13 Oct 1993 10:28:45 +0100 Sender: Guido.van.Rossum@cwi.nl > Note that "f" in both functions is a local variable, so you're not > really creating new symbols. You need to "return eval('f')", instead > of "return f" in my python version, since "f" is not known to be a > local variable statically (you could also do an initial "f = None", > to avoid having to "eval('f')"). This illustrates an interesting fine point of Python's eval/exec semantics: if exec() introduces a new name in the local namespace, the "compiler" can't know about it and any references to it later will fail mysteriously (since it actually exists in the dictionary of local variables but the generated pseudo code will use a "global variable reference" and fail to find it). For example, if you write i = 1 def func(): j = 1 return i, j then the "compiler" (which generates pseudo code for the Python interpreter) sees that there is a local variable j bot no local variable i, so it will generate a local reference for returning j but a global reference for returning i. The reason for doing so is that this speeds up both kinds of references: global references don't first have to do an unsuccessful lookup in the dictionary of local variables, and (starting in 0.9.9) local references are speeded up by using an index into a list instead of a dictionary lookup. Note that any assignment by definition creates a local variable unless explicitly declared global first -- 'global' is in fact one of the few statements that is interpreted at compile time instead of at run-time. Also note that for this purpose the compiler keeps track of all local variables, but not of all global variables. Finally, for the really inquiring minds, built-in functions (e.g. len()) and names (i.e. None) are treated as globals here and they *do* suffer one unsuccessful lookup in the table of globals. This means you can override built-in names with local or global names. You can even change the set of built-in functions by modifying the built-in module 'builtin' (soon to be renamed to '__builtin__' to emphasize its special status, like '__main__'). The effect of all this is that, if the only assignment to a variable is hidden inside an exec(), the compiler can't know about it at the time the containing code is being compiled and it will thus assume it is a global variable. (The exec() can't modify the containing code -- it only generates new code for what is passed to it.) My preferred solution is indeed an initial assignment "f = None". You deserve credit for inventing the alternative "return eval('f')". However, though shorter in lines of code, involves the overhead of parsing the string 'f' on each execution. --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> To: Mark Lutz <lutz@xvt.com> cc: janssen@parc.xerox.com (Bill Janssen), python-list@cwi.nl Subject: Re: Some python comments/questions In-reply-to: Your message of "Tue, 12 Oct 1993 11:41:36 MDT." <199310121741.AA18144@zeus.xvt.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Wed, 13 Oct 1993 10:28:45 +0100 Sender: guido > Note that "f" in both functions is a local variable, so you're not > really creating new symbols. You need to "return eval('f')", instead > of "return f" in my python version, since "f" is not known to be a > local variable statically (you could also do an initial "f = None", > to avoid having to "eval('f')"). This illustrates an interesting fine point of Python's eval/exec semantics: if exec() introduces a new name in the local namespace, the "compiler" can't know about it and any references to it later will fail mysteriously (since it actually exists in the dictionary of local variables but the generated pseudo code will use a "global variable reference" and fail to find it). For example, if you write i = 1 def func(): j = 1 return i, j then the "compiler" (which generates pseudo code for the Python interpreter) sees that there is a local variable j bot no local variable i, so it will generate a local reference for returning j but a global reference for returning i. The reason for doing so is that this speeds up both kinds of references: global references don't first have to do an unsuccessful lookup in the dictionary of local variables, and (starting in 0.9.9) local references are speeded up by using an index into a list instead of a dictionary lookup. Note that any assignment by definition creates a local variable unless explicitly declared global first -- 'global' is in fact one of the few statements that is interpreted at compile time instead of at run-time. Also note that for this purpose the compiler keeps track of all local variables, but not of all global variables. Finally, for the really inquiring minds, built-in functions (e.g. len()) and names (i.e. None) are treated as globals here and they *do* suffer one unsuccessful lookup in the table of globals. This means you can override built-in names with local or global names. You can even change the set of built-in functions by modifying the built-in module 'builtin' (soon to be renamed to '__builtin__' to emphasize its special status, like '__main__'). The effect of all this is that, if the only assignment to a variable is hidden inside an exec(), the compiler can't know about it at the time the containing code is being compiled and it will thus assume it is a global variable. (The exec() can't modify the containing code -- it only generates new code for what is passed to it.) My preferred solution is indeed an initial assignment "f = None". You deserve credit for inventing the alternative "return eval('f')". However, though shorter in lines of code, involves the overhead of parsing the string 'f' on each execution. --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA01475 (5.65b/3.11/CWI-Amsterdam); Wed, 13 Oct 1993 10:57:42 +0100 Received: by voorn.cwi.nl with SMTP id AA03031 (5.65b/3.8/CWI-Amsterdam); Wed, 13 Oct 1993 10:57:41 +0100 Message-Id: <9310130957.AA03031=guido@voorn.cwi.nl> To: Bill Janssen <janssen@parc.xerox.com> Cc: python-list@cwi.nl Subject: Re: Python and UI In-Reply-To: Your message of "Tue, 12 Oct 1993 18:02:56 MDT." <8gipD08B0KGWFDkAp_@holmes.parc.xerox.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Wed, 13 Oct 1993 10:57:41 +0100 Sender: Guido.van.Rossum@cwi.nl > Another tack might be to drop the use of STDWIN, and substitute > something else that's already been ported. SUIT comes to mind, for > example. I have had a look at SUIT, and even have half a Python interface for it lying on a shelf somewhere. (Someone want to finish it?) I like what SUIT does for simple interfaces but am not convinced that it can replace STDWIN -- I seem to remember that you always get exactly one top-level window, and I don't recollect there being a non-X11 version. (In fact, I see SUIT as almost complementary to STDWIN.) > A system that might better match Python's perspicuity, though, is > something more like Joel Bartlett's EZD > (ftp://gatekeeper.dec.com/pub/DEC/ezd/). Haven't seen it yet. Anybody else know about it? --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> To: Bill Janssen <janssen@parc.xerox.com> cc: python-list Subject: Re: Python and UI In-reply-to: Your message of "Tue, 12 Oct 1993 18:02:56 MDT." <8gipD08B0KGWFDkAp_@holmes.parc.xerox.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Wed, 13 Oct 1993 10:57:41 +0100 Sender: guido > Another tack might be to drop the use of STDWIN, and substitute > something else that's already been ported. SUIT comes to mind, for > example. I have had a look at SUIT, and even have half a Python interface for it lying on a shelf somewhere. (Someone want to finish it?) I like what SUIT does for simple interfaces but am not convinced that it can replace STDWIN -- I seem to remember that you always get exactly one top-level window, and I don't recollect there being a non-X11 version. (In fact, I see SUIT as almost complementary to STDWIN.) > A system that might better match Python's perspicuity, though, is > something more like Joel Bartlett's EZD > (ftp://gatekeeper.dec.com/pub/DEC/ezd/). Haven't seen it yet. Anybody else know about it? --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA01721 (5.65b/3.11/CWI-Amsterdam); Wed, 13 Oct 1993 11:07:04 +0100 Received: by voorn.cwi.nl with SMTP id AA03066 (5.65b/3.8/CWI-Amsterdam); Wed, 13 Oct 1993 11:07:03 +0100 Message-Id: <9310131007.AA03066=guido@voorn.cwi.nl> To: Quentin Stafford-Fraser <Fraser@europarc.xerox.com> Cc: python-list@cwi.nl Subject: Re: Some python comments/questions (correction) In-Reply-To: Your message of "Wed, 13 Oct 1993 02:24:17 MDT." <199310130924.AA28934@eros.EuroPARC.Xerox.COM> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Wed, 13 Oct 1993 11:07:03 +0100 Sender: Guido.van.Rossum@cwi.nl > Good - I'm thinking of doing a Modula-3 interface, but I'm waiting > for the name changes... You don't have to wait for the name changes -- all the new names are in the 0.9.9 release (see python/misc/NAMING and python/misc/RENAMING). The new filenames aren't in place yet but you can count on <Py/Python.h> to replace "allobjects.h" plus a few more that are needed by all or most extension modules. > I have to say that I don't think the 'primes' program included in > the BLURB document is a good example of Python's clarity and > ease-of-use. We need a clear bit of sample code that makes people say > "Hey, this is worth downloading" when it appears on comp.sources. Hmm, that is indeed a somewhat convoluted bit of code. I think we would need several short examples, highlighting different aspects of the language: a simple numerical algorithm (printing Fibonacci numbers? who can think of a more interesting example?), some I/O and system calls, some object-oriented stuff, some windowing (would an example using Motif be a better choice than one for STDWIN?). I guess nothing would convince die-hard perl hacks because there's always a shorter way in Perl, but for those who are afraid of Perl it might actually work to compare a few cases of Python and Perl code... (Though of course it is much more dramatic to compare Python with equivalent C programs...) --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> To: Quentin Stafford-Fraser <Fraser@europarc.xerox.com> cc: python-list@cwi.nl Subject: Re: Some python comments/questions (correction) In-reply-to: Your message of "Wed, 13 Oct 1993 02:24:17 MDT." <199310130924.AA28934@eros.EuroPARC.Xerox.COM> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Wed, 13 Oct 1993 11:07:03 +0100 Sender: guido > Good - I'm thinking of doing a Modula-3 interface, but I'm waiting > for the name changes... You don't have to wait for the name changes -- all the new names are in the 0.9.9 release (see python/misc/NAMING and python/misc/RENAMING). The new filenames aren't in place yet but you can count on <Py/Python.h> to replace "allobjects.h" plus a few more that are needed by all or most extension modules. > I have to say that I don't think the 'primes' program included in > the BLURB document is a good example of Python's clarity and > ease-of-use. We need a clear bit of sample code that makes people say > "Hey, this is worth downloading" when it appears on comp.sources. Hmm, that is indeed a somewhat convoluted bit of code. I think we would need several short examples, highlighting different aspects of the language: a simple numerical algorithm (printing Fibonacci numbers? who can think of a more interesting example?), some I/O and system calls, some object-oriented stuff, some windowing (would an example using Motif be a better choice than one for STDWIN?). I guess nothing would convince die-hard perl hacks because there's always a shorter way in Perl, but for those who are afraid of Perl it might actually work to compare a few cases of Python and Perl code... (Though of course it is much more dramatic to compare Python with equivalent C programs...) --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Wed, 13 Oct 1993 11:34:24 +0100 Replied: "Quentin Stafford-Fraser <Fraser@europarc.xerox.com> python-list@cwi.nl" Received: from alpha.Xerox.COM by charon.cwi.nl with SMTP id AA02232 (5.65b/3.11/CWI-Amsterdam); Wed, 13 Oct 1993 11:30:48 +0100 Received: from eros.EuroPARC.Xerox.COM ([13.1.252.143]) by alpha.xerox.com with SMTP id <12093>; Wed, 13 Oct 1993 03:30:24 PDT Received: by eros.EuroPARC.Xerox.COM with SMTP (5.65c/IDA-1.2.9) id AA29223; Wed, 13 Oct 1993 11:29:34 +0100 Message-Id: <199310131029.AA29223@eros.EuroPARC.Xerox.COM> To: python-list@cwi.nl Subject: Re: Some python comments/questions (correction) In-Reply-To: Your message of "Wed, 13 Oct 93 03:07:03 PDT." <9310131007.AA03066=guido@voorn.cwi.nl> Date: Wed, 13 Oct 1993 03:29:33 PDT From: Quentin Stafford-Fraser <Fraser@europarc.xerox.com> > You don't have to wait for the name changes -- all the new names are > in the 0.9.9 release (see python/misc/NAMING and > python/misc/RENAMING). Ah, well they're there if you're using C, because they're #define'd, but if you're using another language then you need to know the names that will be seen by the linker. Quentin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Quentin Stafford-Fraser Tel: +44 223 341521 Rank Xerox EuroPARC, Fax: +44 223 341510 61 Regent Street, Home: +44 223 324451 Cambridge, CB2 1AB United Kingdom Fraser@europarc.xerox.com You can retrieve my pgp public key using "finger qs101@osprey.cl.cam.ac.uk" Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA02307 (5.65b/3.11/CWI-Amsterdam); Wed, 13 Oct 1993 11:34:25 +0100 Received: by voorn.cwi.nl with SMTP id AA03159 (5.65b/3.8/CWI-Amsterdam); Wed, 13 Oct 1993 11:34:24 +0100 Message-Id: <9310131034.AA03159=guido@voorn.cwi.nl> To: Quentin Stafford-Fraser <Fraser@europarc.xerox.com> Cc: python-list@cwi.nl Subject: Re: Some python comments/questions (correction) In-Reply-To: Your message of "Wed, 13 Oct 1993 03:29:33 MDT." <199310131029.AA29223@eros.EuroPARC.Xerox.COM> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Wed, 13 Oct 1993 11:34:24 +0100 Sender: Guido.van.Rossum@cwi.nl > > You don't have to wait for the name changes -- all the new names are > > in the 0.9.9 release (see python/misc/NAMING and > > python/misc/RENAMING). > > Ah, well they're there if you're using C, because they're #define'd, > but if you're using another language then you need to know the names > that will be seen by the linker. Well you could run the script "python/demo/scripts/fixcid.py" over the distributed source. This should fix 99% of the identifiers... Or you could invert the definitions of the "rename1.h" header file. --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> To: Quentin Stafford-Fraser <Fraser@europarc.xerox.com> cc: python-list@cwi.nl Subject: Re: Some python comments/questions (correction) In-reply-to: Your message of "Wed, 13 Oct 1993 03:29:33 MDT." <199310131029.AA29223@eros.EuroPARC.Xerox.COM> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Wed, 13 Oct 1993 11:34:24 +0100 Sender: guido > > You don't have to wait for the name changes -- all the new names are > > in the 0.9.9 release (see python/misc/NAMING and > > python/misc/RENAMING). > > Ah, well they're there if you're using C, because they're #define'd, > but if you're using another language then you need to know the names > that will be seen by the linker. Well you could run the script "python/demo/scripts/fixcid.py" over the distributed source. This should fix 99% of the identifiers... Or you could invert the definitions of the "rename1.h" header file. --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Wed, 13 Oct 1993 16:41:30 +0100 Replied: "python-list " Received: from schelvis.cwi.nl by charon.cwi.nl with SMTP id AA05930 (5.65b/3.11/CWI-Amsterdam); Wed, 13 Oct 1993 14:44:49 +0100 Received: by schelvis.cwi.nl with SMTP id AA09128 (5.65b/3.8/CWI-Amsterdam); Wed, 13 Oct 1993 14:44:48 +0100 Message-Id: <9310131344.AA09128=jack@schelvis.cwi.nl> To: Guido.van.Rossum@cwi.nl Cc: Mark Lutz <lutz@xvt.com>, janssen@parc.xerox.com (Bill Janssen), python-list@cwi.nl Subject: Re: Some python comments/questions In-Reply-To: Message by Guido.van.Rossum@cwi.nl , Wed, 13 Oct 1993 10:28:45 +0100 , <9310130928.AA02952=guido@voorn.cwi.nl> Organisation: Multi-media group, CWI, Kruislaan 413, Amsterdam Phone: +31 20 5924098(work), +31 20 5924199 (fax), +31 20 6160335(home) X-Last-Band-Seen: Holy Rollers, Muffs (Melkweg, 2-10) X-Mini-Review: Eventful. Date: Wed, 13 Oct 1993 14:44:48 +0100 From: Jack Jansen <Jack.Jansen@cwi.nl> Recently, Guido.van.Rossum@cwi.nl said: > > Note that "f" in both functions is a local variable, so you're not > > really creating new symbols. You need to "return eval('f')", instead > > of "return f" in my python version, since "f" is not known to be a > > local variable statically (you could also do an initial "f = None", > > to avoid having to "eval('f')"). > > This illustrates an interesting fine point of Python's eval/exec > semantics: if exec() introduces a new name in the local namespace, the > "compiler" can't know about it and any references to it later will > fail mysteriously (since it actually exists in the dictionary of local > variables but the generated pseudo code will use a "global variable > reference" and fail to find it). I often get bitten by this. Would it be possible to let eval() set some flag or something whereby either the compiler or the runtime code would stop accessing local variable the cheap way, but go through the dictionary instead? -- Jack Jansen | If I can't dance I don't want to be part of Jack.Jansen@cwi.nl | your revolution -- Emma Goldman uunet!cwi.nl!jack G=Jack;S=Jansen;O=cwi;PRMD=surf;ADMD=400net;C=nl Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA07811 (5.65b/3.11/CWI-Amsterdam); Wed, 13 Oct 1993 16:19:15 +0100 To: Guido.van.Rossum@cwi.nl Cc: Fraser@europarc.xerox.com, python-list@cwi.nl In-Reply-To: <9310131007.AA03066=guido@voorn.cwi.nl> (Guido.van.Rossum@cwi.nl) Subject: Re: Some python comments/questions (correction) X-Signed: PGP-Attached-clearsig-2-3, iQCVAgUBLLwcK2nDnXuZ0ONVAQETlwP+O7wMbVvke41Pm5JjtHTE0wzgr4sjWHLQ fvrO1t6oI6hSXvvfftSdzCF/8KdwovSEttkzozREtWLQvZSKcomD3bCsJ/fBYjuA KP8GbhCi32x2lljyRQBUlHjlH6U1VnCeB17oKzXBsrg/u5mzhfxm3+RGHcYTW896 3Xh/1ChR2Kc= X-Organization: Mark V Systems Ltd. X-Address: 16400 Ventura Blvd Suite 303, Encino, Ca, 91436, USA X-Phone: +1 818 995 7671 (work), +1 818 995 4267 (fax) Date: Wed, 13 Oct 93 8:18:11 PDT From: lance@markv.com Sender: lance@markv.com Message-Id: <9310130818.aa28778@hermix.markv.com> Source-Info: From (or Sender) name not authenticated. > > I have to say that I don't think the 'primes' program included in > > the BLURB document is a good example of Python's clarity and > > ease-of-use. We need a clear bit of sample code that makes people say > > "Hey, this is worth downloading" when it appears on comp.sources. > > Hmm, that is indeed a somewhat convoluted bit of code. I think we > would need several short examples, highlighting different aspects of > the language: a simple numerical algorithm (printing Fibonacci > numbers? who can think of a more interesting example?), some I/O and > system calls, some object-oriented stuff, some windowing (would an > example using Motif be a better choice than one for STDWIN?). I think an example using Motif would be a better choice. More people will look at it and say "I could use that!". Currently a lot of people are moving to TCL from C because of the Tk package (Motif interface for those who don't know). If people saw how clean Python is with a Motif interface, I think some would drop TCL/Tk and go with Python.. Python is a MUCH cleaner language. - -- Lance Ellinghouse lance@markv.com 1231 bit key fingerprint = 56 DA 31 0C 17 51 36 6A 4E D4 E0 11 D9 B8 06 0A 1024 bit key fingerprint = 66 2C 75 F2 E9 1C 32 84 3A E3 B0 5E 48 01 4C 37 You can receive my Public Key by `finger lance@markv.com` Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA08319 (5.65b/3.11/CWI-Amsterdam); Wed, 13 Oct 1993 16:41:34 +0100 Received: by voorn.cwi.nl with SMTP id AA04116 (5.65b/3.8/CWI-Amsterdam); Wed, 13 Oct 1993 16:41:31 +0100 Message-Id: <9310131541.AA04116=guido@voorn.cwi.nl> To: python-list@cwi.nl Subject: Re: Some python comments/questions In-Reply-To: Your message of "Wed, 13 Oct 1993 14:44:48 MET." <9310131344.AA09128=jack@schelvis.cwi.nl> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Wed, 13 Oct 1993 16:41:30 +0100 Sender: Guido.van.Rossum@cwi.nl > I often get bitten by this. Would it be possible to let eval() set > some flag or something whereby either the compiler or the runtime code > would stop accessing local variable the cheap way, but go through the > dictionary instead? I walked over to Jack's office to explain why this wasn't a good idea, and in the ensueing discussion we suddenly came up with the following solution: make exec a statement instead of a function. The syntax would be exec <expression> [in <expression> [, <expression>]] and the compiler can switch off any optimizations for functions containing exec statements. There is a precedent for this: the same happens when the compiler sees "from <module> import *", because it can't tell what local variables the star will introduce. The change will break some existing Python code: statements calling exec() with an explicit global and/or local dictionary. The majority of exec() function calls will still work since the extra parentheses are harmless. How about it? --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> To: python-list Subject: Re: Some python comments/questions In-reply-to: Your message of "Wed, 13 Oct 1993 14:44:48 MET." <9310131344.AA09128=jack@schelvis.cwi.nl> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Wed, 13 Oct 1993 16:41:30 +0100 Sender: guido > I often get bitten by this. Would it be possible to let eval() set > some flag or something whereby either the compiler or the runtime code > would stop accessing local variable the cheap way, but go through the > dictionary instead? I walked over to Jack's office to explain why this wasn't a good idea, and in the ensueing discussion we suddenly came up with the following solution: make exec a statement instead of a function. The syntax would be exec <expression> [in <expression> [, <expression>]] and the compiler can switch off any optimizations for functions containing exec statements. There is a precedent for this: the same happens when the compiler sees "from <module> import *", because it can't tell what local variables the star will introduce. The change will break some existing Python code: statements calling exec() with an explicit global and/or local dictionary. The majority of exec() function calls will still work since the extra parentheses are harmless. How about it? --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from sapling.surfnet.nl by charon.cwi.nl with SMTP id AA08972 (5.65b/3.11/CWI-Amsterdam); Wed, 13 Oct 1993 17:08:57 +0100 X400-Received: by mta sapling.surfnet.nl in /PRMD=surf/ADMD=400net/C=nl/; Relayed; Wed, 13 Oct 1993 17:08:56 +0100 X400-Received: by /PRMD=uk.ac/ADMD= /C=gb/; Relayed; Wed, 13 Oct 1993 17:07:45 +0100 X400-Received: by /PRMD=UK.AC/ADMD= /C=GB/; Relayed; Wed, 13 Oct 1993 17:07:16 +0100 X400-Received: by /PRMD=UK.AC/ADMD= /C=GB/; Relayed; Wed, 13 Oct 1993 17:03:56 +0100 X400-Received: by /PRMD=UK.AC/ADMD= /C=GB/; Relayed; Wed, 13 Oct 1993 17:03:56 +0100 Date: Wed, 13 Oct 1993 17:03:56 +0100 X400-Originator: peter%robots.oxford.ac.uk@prg.oxford.ac.uk X400-Recipients: python-list@cwi.nl X400-Mts-Identifier: [/PRMD=UK.AC/ADMD= /C=GB/;<9310131603.AA20864@quickly.robo] X400-Content-Type: P2-1984 (2) Content-Identifier: Re: Some pyth... From: peter@robots.oxford.ac.uk Message-Id: <9310131603.AA20864@quickly.robots.ox.ac.uk> To: python-list@cwi.nl Subject: Re: Some python comments/questions (correction) > From lance@markv.com Wed Oct 13 16:23:08 1993 > I think an example using Motif would be a better choice. More people > will look at it and say "I could use that!". Currently a lot of people > are moving to TCL from C because of the Tk package (Motif interface > for those who don't know). If people saw how clean Python is with a > Motif interface, I think some would drop TCL/Tk and go with Python.. > Python is a MUCH cleaner language. What about a python interface to tk? Has anyone done it? Pete. Replied: Wed, 13 Oct 1993 21:34:13 +0100 Replied: "lance@markv.com python-list" Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA09117 (5.65b/3.11/CWI-Amsterdam); Wed, 13 Oct 1993 17:16:42 +0100 To: Guido.van.Rossum@cwi.nl Cc: python-list@cwi.nl In-Reply-To: <9310131541.AA04116=guido@voorn.cwi.nl> (Guido.van.Rossum@cwi.nl) Subject: Re: Some python comments/questions X-Organization: Mark V Systems Ltd. X-Address: 16400 Ventura Blvd Suite 303, Encino, Ca, 91436, USA X-Phone: +1 818 995 7671 (work), +1 818 995 4267 (fax) Date: Wed, 13 Oct 93 9:15:47 PDT From: lance@markv.com Sender: lance@markv.com Message-Id: <9310130915.aa04945@hermix.markv.com> Source-Info: From (or Sender) name not authenticated. > > I often get bitten by this. Would it be possible to let eval() set > > some flag or something whereby either the compiler or the runtime code > > would stop accessing local variable the cheap way, but go through the > > dictionary instead? > > I walked over to Jack's office to explain why this wasn't a good idea, > and in the ensueing discussion we suddenly came up with the following > solution: make exec a statement instead of a function. The syntax > would be > > exec <expression> [in <expression> [, <expression>]] > > and the compiler can switch off any optimizations for functions > containing exec statements. There is a precedent for this: the same > happens when the compiler sees "from <module> import *", because it > can't tell what local variables the star will introduce. > > The change will break some existing Python code: statements calling > exec() with an explicit global and/or local dictionary. The majority > of exec() function calls will still work since the extra parentheses > are harmless. > > How about it? PLEASE DON'T!!!!! I have a bunch of code that relies on passing in explicit local and global dictionaries!! My code does the following: co = code object loaded from a file using marshal.load() l_ns = {} exec(co,{},l_ns) exec(co,l_ns,l_ns) I then call functions as: l_ns['function_name'](args) Each l_ns is a completely seperate name space and seperate environment! I need this! Please don't take it away! Or tell me a better way to do it. -- Lance Ellinghouse lance@markv.com 1231 bit key fingerprint = 56 DA 31 0C 17 51 36 6A 4E D4 E0 11 D9 B8 06 0A 1024 bit key fingerprint = 66 2C 75 F2 E9 1C 32 84 3A E3 B0 5E 48 01 4C 37 You can receive my Public Key by `finger lance@markv.com` Replied: Wed, 13 Oct 1993 21:21:45 +0100 Replied: "Mark Lutz <lutz@xvt.com> " Received: from csn.org by charon.cwi.nl with SMTP id AA09738 (5.65b/3.11/CWI-Amsterdam); Wed, 13 Oct 1993 17:40:07 +0100 Received: by csn.org with UUCP id AA06557 (5.65c/IDA-1.4.4 for python-list@cwi.nl); Wed, 13 Oct 1993 10:38:46 -0600 Received: by zeus.xvt.com id AA00984 (5.65c/IDA-1.4.4); Wed, 13 Oct 1993 10:30:34 -0600 From: Mark Lutz <lutz@xvt.com> Message-Id: <199310131630.AA00984@zeus.xvt.com> Subject: Re: Some python comments/questions (correction) To: Fraser@europarc.xerox.com (Quentin Stafford-Fraser) Date: Wed, 13 Oct 93 10:30:33 MDT Cc: python-list@cwi.nl In-Reply-To: <199310130924.AA28934@eros.EuroPARC.Xerox.COM>; from "Quentin Stafford-Fraser" at Oct 13, 93 2:24 am > I have to say that I don't think the 'primes' program included in the BLURB document is a good example of Python's clarity and ease-of-use. We need a clear bit of sample code that makes people say "Hey, this is worth downloading" when it appears on comp.> sources. > > Anybody like to volunteer some? I've written a forward/backward chaining expert system shell in Python which is a bit long (multiple modules), but demonstrates using Python for serious development (and something you'd have to be insane to try in Perl/TCL/etc...). I'd be happy to donate the code if appropriate. Mark Lutz lutz@xvt.com Received: from quark.phys.washington.edu by charon.cwi.nl with SMTP id AA11053 (5.65b/3.11/CWI-Amsterdam); Wed, 13 Oct 1993 18:05:04 +0100 Received: by quark.phys.washington.edu (5.65/UW-NDC Revision: 2.25 ) id AA02440; Wed, 13 Oct 93 10:05:01 -0700 Date: Wed, 13 Oct 1993 09:59:47 -0700 (PDT) From: Jon Eisenberg <jke@u.washington.edu> Subject: Re: Some python comments/questions To: Guido.van.Rossum@cwi.nl In-Reply-To: <9310131541.AA04116=guido@voorn.cwi.nl> Message-Id: <Pine.3.07.9310130945.A2300-b100000@quark.phys.washington.edu> Mime-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII On Wed, 13 Oct 1993 Guido.van.Rossum@cwi.nl wrote: > The change will break some existing Python code: statements calling > exec() with an explicit global and/or local dictionary. The majority > of exec() function calls will still work since the extra parentheses > are harmless. > > How about it? > > --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> I am developing a data analysis application using python as the interface and user programming language. Your proposed change in exec would seem to break it. I use the feature of passing an explicit dictionary for the following reason. I have a database with named entries on which I wish to perform calculations. To evaluate an expression of the variables names, I create an object with features named as the database entries are (by taking an empty class and adding the features to it), then pass the objects dictionary as the local namespace to the exec() call. That way I don't have to parse the expression or clutter the local name space with variables of the same name as the db entries. How could I accomplish the same after your proposed changes? --Jon -- Jon Eisenberg High Energy Physics Lab e-mail: jke@u.washington.edu Physics Dept., FM-15 (or jke@uwaphast.bitnet) Univ. of Washington phone: 206-543-6886 office Seattle, WA 98195 fax: 206-685-0635 Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA11535 (5.65b/3.11/CWI-Amsterdam); Wed, 13 Oct 1993 18:34:29 +0100 To: peter@robots.ox.ac.uk Cc: python-list@cwi.nl In-Reply-To: <9310131603.AA20864@quickly.robots.ox.ac.uk> (peter@robots.ox.ac.uk) Subject: Re: Some python comments/questions (correction) X-Organization: Mark V Systems Ltd. X-Address: 16400 Ventura Blvd Suite 303, Encino, Ca, 91436, USA X-Phone: +1 818 995 7671 (work), +1 818 995 4267 (fax) Date: Wed, 13 Oct 93 10:33:41 PDT From: lance@markv.com Sender: lance@markv.com Message-Id: <9310131033.aa12989@hermix.markv.com> Source-Info: From (or Sender) name not authenticated. > > From lance@markv.com Wed Oct 13 16:23:08 1993 > > I think an example using Motif would be a better choice. More people > > will look at it and say "I could use that!". Currently a lot of people > > are moving to TCL from C because of the Tk package (Motif interface > > for those who don't know). If people saw how clean Python is with a > > Motif interface, I think some would drop TCL/Tk and go with Python.. > > Python is a MUCH cleaner language. > > What about a python interface to tk? Has anyone done it? Why bother? the Motif interface that comes wih Python 0.9.9 is much cleaner than tk will ever be! -- Lance Ellinghouse lance@markv.com 1231 bit key fingerprint = 56 DA 31 0C 17 51 36 6A 4E D4 E0 11 D9 B8 06 0A 1024 bit key fingerprint = 66 2C 75 F2 E9 1C 32 84 3A E3 B0 5E 48 01 4C 37 You can receive my Public Key by `finger lance@markv.com` Received: from ohmg.hydro.on.ca by charon.cwi.nl with SMTP id AA12098 (5.65b/3.11/CWI-Amsterdam); Wed, 13 Oct 1993 19:15:07 +0100 Received: from eagle.hydro.on.ca by ohmg.hydro.on.ca with SMTP id <67324>; Wed, 13 Oct 1993 14:37:41 -0400 Received: by eagle.hydro.on.ca (4.1/SMI-4.1) id AA20512; Wed, 13 Oct 93 14:09:49 EDT Received: from thor.rd.hydro.on.ca by ohrd.rd.hydro.on.ca with SMTP id AA25586 (5.65c/IDA-1.4.4 for python-list@cwi.nl); Wed, 13 Oct 1993 14:14:37 -0400 Received: by thor.rd.hydro.on.ca id AA15275 (5.65c/IDA-1.4.4 for python-list@cwi.nl); Wed, 13 Oct 1993 14:16:42 -0400 Date: Wed, 13 Oct 1993 14:16:42 -0400 From: Martin Green <martin.a.green@hydro.on.ca> Message-Id: <199310131816.AA15275@thor.rd.hydro.on.ca> To: python-list@cwi.nl Subject: Re: Some python comments/questions (correction) In-Reply-To: <9310131603.AA20864@quickly.robots.ox.ac.uk> References: <9310131603.AA20864@quickly.robots.ox.ac.uk> On October 13 at 12:03:56 peter@robots.ox.ac.uk wrote: > > From lance@markv.com Wed Oct 13 16:23:08 1993 > > I think an example using Motif would be a better choice. More people > > will look at it and say "I could use that!". Currently a lot of people > > are moving to TCL from C because of the Tk package (Motif interface > > for those who don't know). If people saw how clean Python is with a > > Motif interface, I think some would drop TCL/Tk and go with Python.. > > Python is a MUCH cleaner language. > > What about a python interface to tk? Has anyone done it? > I raised this with Guido and John Ousterhout (author of TCL/Tk) several months ago, and even agreed to do it if I could find the time. Although I have been following this list with great interest, I have been too busy working on a project using TCL to properly learn Python, or take on the Tk project. Its a chicken and egg situation :-(. Tk is a terrific system that looks like, but is distinct from, Motif. It relies heavily on the TCL interpreter, so adding Tk support to Python also means adding TCL. It would probably be easiest to add a Python interpreter to Tk's windowing shell (wish), rather than adding TCL/Tk to Python. Martin A. Green Net : green@rd.hydro.on.ca Ontario Hydro Technologies Tel : (416) 207-5745 800 Kipling Ave, KR260 FAX : (416) 207-5622 Toronto, Ontario, CANADA, M8Z5S4 Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA13988 (5.65b/3.11/CWI-Amsterdam); Wed, 13 Oct 1993 21:34:14 +0100 Received: by voorn.cwi.nl with SMTP id AA04541 (5.65b/3.8/CWI-Amsterdam); Wed, 13 Oct 1993 21:34:13 +0100 Message-Id: <9310132034.AA04541=guido@voorn.cwi.nl> To: lance@markv.com Cc: python-list@cwi.nl Subject: Re: Some python comments/questions In-Reply-To: Your message of "Wed, 13 Oct 1993 09:15:47 MDT." <9310130915.aa04945@hermix.markv.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Wed, 13 Oct 1993 21:34:13 +0100 Sender: Guido.van.Rossum@cwi.nl Lance Ellinghouse: > PLEASE DON'T!!!!! I have a bunch of code that relies on passing in > explicit local and global dictionaries!! and Jon Eisberg: > I am developing a data analysis application using python as the interface > and user programming language. Your proposed change in exec would seem to > break it. Sorry folks, that's not what I meant to say! Your functionality will of course still be supported. Here's my proposed syntax again: exec <expression> [in <expression> [, <expression>]] The optional "in ..." part would be used to pass the global/local dictionary as with the current exec() function (and using this feature would mean the compiler did not have to stop optimizing locals). My remark that the change would "break" existing code was meant to apply at the syntactic level -- you will have to change all your lines that currently read exec(a, b, c) into exec a in b, c (and I will even make a script that does this painlessly, just as for other incompatible syntax changes in the past). Sorry about the confusion, --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> To: lance@markv.com cc: python-list Subject: Re: Some python comments/questions In-reply-to: Your message of "Wed, 13 Oct 1993 09:15:47 MDT." <9310130915.aa04945@hermix.markv.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Wed, 13 Oct 1993 21:34:13 +0100 Sender: guido Lance Ellinghouse: > PLEASE DON'T!!!!! I have a bunch of code that relies on passing in > explicit local and global dictionaries!! and Jon Eisberg: > I am developing a data analysis application using python as the interface > and user programming language. Your proposed change in exec would seem to > break it. Sorry folks, that's not what I meant to say! Your functionality will of course still be supported. Here's my proposed syntax again: exec <expression> [in <expression> [, <expression>]] The optional "in ..." part would be used to pass the global/local dictionary as with the current exec() function (and using this feature would mean the compiler did not have to stop optimizing locals). My remark that the change would "break" existing code was meant to apply at the syntactic level -- you will have to change all your lines that currently read exec(a, b, c) into exec a in b, c (and I will even make a script that does this painlessly, just as for other incompatible syntax changes in the past). Sorry about the confusion, --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Wed, 13 Oct 1993 22:42:24 +0100 Replied: "Bill Janssen <janssen@parc.xerox.com> " Received: from alpha.Xerox.COM by charon.cwi.nl with SMTP id AA14079 (5.65b/3.11/CWI-Amsterdam); Wed, 13 Oct 1993 21:42:44 +0100 Received: from holmes.parc.xerox.com ([13.1.100.162]) by alpha.xerox.com with SMTP id <12209>; Wed, 13 Oct 1993 13:42:24 PDT Received: by holmes.parc.xerox.com id <16134>; Wed, 13 Oct 1993 13:42:21 -0700 Received: from Messages.7.15.N.CUILIB.3.45.SNAP.NOT.LINKED.holmes.parc.xerox.com.sun4.41 via MS.5.6.holmes.parc.xerox.com.sun4_41; Wed, 13 Oct 1993 13:42:11 -0700 (PDT) Message-Id: <Egj6UXwB0KGW9Dk4lJ@holmes.parc.xerox.com> Date: Wed, 13 Oct 1993 13:42:11 PDT Sender: Bill Janssen <janssen@parc.xerox.com> From: Bill Janssen <janssen@parc.xerox.com> To: Bill Janssen <janssen@parc.xerox.com>, Guido.van.Rossum@cwi.nl Subject: Re: Python and UI Cc: python-list@cwi.nl In-Reply-To: <9310130957.AA03031=guido@voorn.cwi.nl> References: <9310130957.AA03031=guido@voorn.cwi.nl> Excerpts from direct: 13-Oct-93 Re: Python and UI Guido.van.Rossum@cwi.nl (821) > I like > what SUIT does for simple interfaces but am not convinced that it can > replace STDWIN -- I seem to remember that you always get exactly one > top-level window, and I don't recollect there being a non-X11 version. It's layered on top of srgp, so it should work on the Mac as well (srgp is very much like STDWIN, and has ports to the Mac and X11). But I don't think there's an MS-Windows port... Is there any way to create an STDWIN window without the menubar? Bill Received: from alpha.Xerox.COM by charon.cwi.nl with SMTP id AA14163 (5.65b/3.11/CWI-Amsterdam); Wed, 13 Oct 1993 21:53:36 +0100 Received: from holmes.parc.xerox.com ([13.1.100.162]) by alpha.xerox.com with SMTP id <12212>; Wed, 13 Oct 1993 13:53:15 PDT Received: by holmes.parc.xerox.com id <16134>; Wed, 13 Oct 1993 13:53:07 -0700 Received: from Messages.7.15.N.CUILIB.3.45.SNAP.NOT.LINKED.holmes.parc.xerox.com.sun4.41 via MS.5.6.holmes.parc.xerox.com.sun4_41; Wed, 13 Oct 1993 13:52:57 -0700 (PDT) Message-Id: <ogj6edcB0KGWRDk5x3@holmes.parc.xerox.com> Date: Wed, 13 Oct 1993 13:52:57 PDT Sender: Bill Janssen <janssen@parc.xerox.com> From: Bill Janssen <janssen@parc.xerox.com> To: Guido.van.Rossum@cwi.nl Subject: Re: Some python comments/questions (correction) Cc: python-list@cwi.nl In-Reply-To: <9310131007.AA03066=guido@voorn.cwi.nl> References: <9310131007.AA03066=guido@voorn.cwi.nl> Excerpts from mail: 13-Oct-93 Re: Some python comments/qu.. Guido.van.Rossum@cwi.nl (1438) > some windowing (would an > example using Motif be a better choice than one for STDWIN?). Of course you need the shortest possible hello, world; something like: #! /usr/local/bin/python import stdwin stdwin.message('Hello, World!') Bill Received: from alpha.Xerox.COM by charon.cwi.nl with SMTP id AA14198 (5.65b/3.11/CWI-Amsterdam); Wed, 13 Oct 1993 21:56:02 +0100 Received: from holmes.parc.xerox.com ([13.1.100.162]) by alpha.xerox.com with SMTP id <12214>; Wed, 13 Oct 1993 13:55:46 PDT Received: by holmes.parc.xerox.com id <16134>; Wed, 13 Oct 1993 13:55:38 -0700 Received: from Messages.7.15.N.CUILIB.3.45.SNAP.NOT.LINKED.holmes.parc.xerox.com.sun4.41 via MS.5.6.holmes.parc.xerox.com.sun4_41; Wed, 13 Oct 1993 13:55:28 -0700 (PDT) Message-Id: <wgj6h0YB0KGWJDk6Vw@holmes.parc.xerox.com> Date: Wed, 13 Oct 1993 13:55:28 PDT Sender: Bill Janssen <janssen@parc.xerox.com> From: Bill Janssen <janssen@parc.xerox.com> To: Guido.van.Rossum@cwi.nl Subject: Re: Some python comments/questions Cc: python-list@cwi.nl In-Reply-To: <9310131541.AA04116=guido@voorn.cwi.nl> References: <9310131541.AA04116=guido@voorn.cwi.nl> Excerpts from mail: 13-Oct-93 Re: Some python comments/qu.. Guido.van.Rossum@cwi.nl (1068) > The change will break some existing Python code: statements calling > exec() with an explicit global and/or local dictionary. The majority > of exec() function calls will still work since the extra parentheses > are harmless. Hmmm. I was sort of counting on having this continue to work. Bill Received: from hopscotch.ksr.com by charon.cwi.nl with SMTP id AA14485 (5.65b/3.11/CWI-Amsterdam); Wed, 13 Oct 1993 22:19:28 +0100 Received: from ksr.com (frankenstein.ksr.com) by hopscotch.ksr.com with SMTP id AA08285; Wed, 13 Oct 1993 17:19:05 -0400 Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA05311; Wed, 13 Oct 93 17:19:39 EDT Received: by kaos.ksr.com (4.1/KSR-2.0) id AA29372; Wed, 13 Oct 93 17:19:37 EDT Message-Id: <9310132119.AA29372@kaos.ksr.com> To: Guido.van.Rossum@cwi.nl Subject: Python examples (was Re: Some python comments/questions (correction)) Cc: python-list@cwi.nl Date: Wed, 13 Oct 93 17:19:36 -0400 From: Tim Peters <tim@ksr.com> > ... a simple numerical algorithm (printing Fibonacci numbers? who can > think of a more interesting example?), ... How about this piece? It's a useful algorithm that manages to illustrate lots of things interesting to number-crunchers: long ints, short ints, floats, implicit & explicit coercions, useful builtin functions, multiple assignment, simple import, painless quick output, & multi-valued functions: print 'approximations to pi' import math top = 31415926535897932385L bottom = 10000000000000000000L p2, p1 = 0, 1 q2, q1 = 1, 0 while q1 < 1000000: quotient, remainder = divmod( top, bottom ) p2, p1 = p1, p2 + quotient * p1 q2, q1 = q1, q2 + quotient * q1 top, bottom = bottom, remainder diff = float(p1)/q1 - math.pi sign = '+' if diff < 0: sign = '-' print p1, '/', q1, '\t= pi', sign, abs(diff) It also illustrates that floating-point output may differ on different machines, which gives every number-cruncher that warm glow of easy familiarity <grin>: approximations to pi 3L / 1L = pi - 0.14159265359 22L / 7L = pi + 0.00126448926735 333L / 106L = pi - 8.32196275291e-05 355L / 113L = pi + 2.66764189405e-07 103993L / 33102L = pi - 5.77890624243e-10 104348L / 33215L = pi + 3.31628058348e-10 208341L / 66317L = pi - 1.22356347276e-10 312689L / 99532L = pi + 2.91433543964e-11 833719L / 265381L = pi - 8.71525074331e-12 1146408L / 364913L = pi + 1.61071156413e-12 4272943L / 1360120L = pi - 4.04121180964e-13 > ... but for those who are afraid of Perl it might actually work to > compare a few cases of Python and Perl code... Perhaps more to the point, if you include _any_ comparison of Python & Perl, it will guarantee a flame war that will keep Python's name active on the Net for months <snicker> ... good-publicity-bad-publicity-just-so-long-as-they-spell-the-name-right-ly y'rs - tim Tim Peters tim@ksr.com not speaking for Kendall Square Research Corp Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA16087 (5.65b/3.11/CWI-Amsterdam); Thu, 14 Oct 1993 00:30:45 +0100 To: Guido.van.Rossum@cwi.nl Cc: python-list@cwi.nl In-Reply-To: <9310132034.AA04541=guido@voorn.cwi.nl> (Guido.van.Rossum@cwi.nl) Subject: Re: Some python comments/questions X-Organization: Mark V Systems Ltd. X-Address: 16400 Ventura Blvd Suite 303, Encino, Ca, 91436, USA X-Phone: +1 818 995 7671 (work), +1 818 995 4267 (fax) Date: Wed, 13 Oct 93 16:29:37 PDT From: lance@markv.com Sender: lance@markv.com Message-Id: <9310131629.aa14070@hermix.markv.com> Source-Info: From (or Sender) name not authenticated. > From charon.cwi.nl!cwi.nl!guido Wed Oct 13 13:38:25 1993 > Cc: python-list@cwi.nl > From: Guido.van.Rossum@cwi.nl > X-Organization: CWI (Centrum voor Wiskunde en Informatica) > X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands > X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) > Date: Wed, 13 Oct 1993 21:34:13 +0100 > Sender: Guido.van.Rossum@cwi.nl > > Lance Ellinghouse: > > PLEASE DON'T!!!!! I have a bunch of code that relies on passing in > > explicit local and global dictionaries!! > > and Jon Eisberg: > > I am developing a data analysis application using python as the interface > > and user programming language. Your proposed change in exec would seem to > > break it. > > Sorry folks, that's not what I meant to say! Your functionality will > of course still be supported. Here's my proposed syntax again: > > exec <expression> [in <expression> [, <expression>]] > > The optional "in ..." part would be used to pass the global/local > dictionary as with the current exec() function (and using this > feature would mean the compiler did not have to stop optimizing > locals). My remark that the change would "break" existing code was > meant to apply at the syntactic level -- you will have to change all > your lines that currently read > > exec(a, b, c) > > into > > exec a in b, c > > (and I will even make a script that does this painlessly, just as for > other incompatible syntax changes in the past). > > Sorry about the confusion, That is a relief! -- Lance Ellinghouse lance@markv.com 1231 bit key fingerprint = 56 DA 31 0C 17 51 36 6A 4E D4 E0 11 D9 B8 06 0A 1024 bit key fingerprint = 66 2C 75 F2 E9 1C 32 84 3A E3 B0 5E 48 01 4C 37 You can receive my Public Key by `finger lance@markv.com` Replied: Thu, 14 Oct 1993 11:17:14 +0100 Replied: "lance@markv.com " Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA16125 (5.65b/3.11/CWI-Amsterdam); Thu, 14 Oct 1993 00:38:08 +0100 To: python-list@cwi.nl Subject: current 'index' file for python FTP site X-Organization: Mark V Systems Ltd. X-Address: 16400 Ventura Blvd Suite 303, Encino, Ca, 91436, USA X-Phone: +1 818 995 7671 (work), +1 818 995 4267 (fax) Date: Wed, 13 Oct 93 16:37:26 PDT From: lance@markv.com Sender: lance@markv.com Message-Id: <9310131637.aa15147@hermix.markv.com> Source-Info: From (or Sender) name not authenticated. Well I FINALLY have a single file in the FTP site I am maintaining for python .py files and stuff like that.. Here is the current 'index' file.. If you can think of a better format, PLEASE let me know what you prefer.. and I will see about putting it together.. ------ Cut Index of ftp.markv.com:/pub/python Files: Dates.py Dates.readme Author: Tim Peters <tim@ksr.com> Description: Date manipulation class See Dates.readme and Dates.py for more info.. -- Lance Ellinghouse lance@markv.com 1231 bit key fingerprint = 56 DA 31 0C 17 51 36 6A 4E D4 E0 11 D9 B8 06 0A 1024 bit key fingerprint = 66 2C 75 F2 E9 1C 32 84 3A E3 B0 5E 48 01 4C 37 You can receive my Public Key by `finger lance@markv.com` Received: from alpha.Xerox.COM by charon.cwi.nl with SMTP id AA16690 (5.65b/3.11/CWI-Amsterdam); Thu, 14 Oct 1993 01:37:33 +0100 Received: from holmes.parc.xerox.com ([13.1.100.162]) by alpha.xerox.com with SMTP id <12293>; Wed, 13 Oct 1993 17:33:31 PDT Received: by holmes.parc.xerox.com id <16134>; Wed, 13 Oct 1993 17:33:19 -0700 Received: from Messages.7.15.N.CUILIB.3.45.SNAP.NOT.LINKED.holmes.parc.xerox.com.sun4.41 via MS.5.6.holmes.parc.xerox.com.sun4_41; Wed, 13 Oct 1993 17:33:12 -0700 (PDT) Message-Id: <0gj9t8kB0KGWFDk75a@holmes.parc.xerox.com> Date: Wed, 13 Oct 1993 17:33:12 PDT Sender: Bill Janssen <janssen@parc.xerox.com> From: Bill Janssen <janssen@parc.xerox.com> To: lance@markv.com Subject: More on Python and UI Cc: python-list@cwi.nl In-Reply-To: <9310131033.aa12989@hermix.markv.com> References: <9310131033.aa12989@hermix.markv.com> Excerpts from mail: 13-Oct-93 Re: Some python comments/qu.. lance@markv.com (889) > Why bother? the Motif interface that comes wih Python 0.9.9 is > much cleaner than tk will ever be! It also bloats python from 1MB to 3MB on the Sun, making it realistically unusable for quick small programs. What Tk has going for it (with Tcl), is that it is quick and small -- it doesn't require the Motif library to be linked in. I think, though, that we could come up with something *much* better than Tk, with more functionality, of equivalent size and speed. STDWIN is, in some ways, a good start. What it could use (from my limited experience with it): 1) a nice Motif-appearance set of widgets, implemented in Python or C, to go on top of it. (A C implementation would be analogous to Tk.) 2) better (faster) access to the text buffer maintained by the textedit widget. The style proposed by EZD would be a nice way to go, as well, and might be easy to map on top of STDWIN (which would mean a 3 layer system: STDWIN on the bottom, "pezd" on top of that, some widget collection on top of that). In EZD, things are done in terms of "graphical objects" (lines, arcs, polygons, text), which can be created and arranged without regard to whether or not any windows actually exist. Groups of graphical objects are called "drawings". Graphical objects can be bound into drawings, and their position and stacking order controlled. Drawings can also then be mapped into "windows". Multiple drawings can be mapped into any window. A drawing may be mapped into more than one window. Optional clipping rects may be defined for each binding of a drawing to a window. Each window can define its own coordinate space. Events like mouse clicks or keystrokes are mapped by EZD to the drawing object on which the event occurred. Redraws are done via callbacks bound to the drawing objects. Each drawing object uses a set of graphical primitives similar to those used in STDWIN. I'd have to re-read the technical report (ftp://gatekeeper.dec.com/pub/DEC/ezd/techreport.psf.Z) to be more accurate than that. Bill Received: from alpha.Xerox.COM by charon.cwi.nl with SMTP id AA16712 (5.65b/3.11/CWI-Amsterdam); Thu, 14 Oct 1993 01:40:43 +0100 Received: from holmes.parc.xerox.com ([13.1.100.162]) by alpha.xerox.com with SMTP id <12297>; Wed, 13 Oct 1993 17:39:01 PDT Received: by holmes.parc.xerox.com id <16134>; Wed, 13 Oct 1993 17:38:50 -0700 Received: from Messages.7.15.N.CUILIB.3.45.SNAP.NOT.LINKED.holmes.parc.xerox.com.sun4.41 via MS.5.6.holmes.parc.xerox.com.sun4_41; Wed, 13 Oct 1993 17:38:38 -0700 (PDT) Message-Id: <wgj9yCwB0KGWFDk7Z=@holmes.parc.xerox.com> Date: Wed, 13 Oct 1993 17:38:38 PDT Sender: Bill Janssen <janssen@parc.xerox.com> From: Bill Janssen <janssen@parc.xerox.com> To: python-list@cwi.nl, Martin Green <martin.a.green@hydro.on.ca> Subject: Re: Some python comments/questions (correction) In-Reply-To: <199310131816.AA15275@thor.rd.hydro.on.ca> References: <9310131603.AA20864@quickly.robots.ox.ac.uk> <199310131816.AA15275@thor.rd.hydro.on.ca> Excerpts from mail: 13-Oct-93 Re: Some python comments/qu.. Martin Green@hydro.on.ca (1436) > Tk is a terrific system that looks like, but is distinct from, Motif. > It relies heavily on the TCL interpreter, so adding Tk support to > Python also means adding TCL. Just say no. Bill Replied: Thu, 14 Oct 1993 17:25:06 +0100 Replied: ""Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> " Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA29632 (5.65b/3.11/CWI-Amsterdam); Thu, 14 Oct 1993 17:21:51 +0100 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa15187; 14 Oct 93 12:21 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA13403; Thu, 14 Oct 1993 12:21:36 -0400 Date: Thu, 14 Oct 1993 12:21:36 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199310141621.AA13403@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: python-list@cwi.nl Subject: Killed One of my python programs, after getting 80% into processing a rather large file, responds with the terse message: Killed and exits. That's certainly not one of MY messages. Maybe it's an OS message ( from IBM AIX 3.2.2 ) Is there anyplace in the python code that might produce that message ? I expect it is a cryptic message from AIX, but I thought I'ld check to see if anyone has ever seen anything similar. - Steve Majewski Received: from ansjovis.cwi.nl by charon.cwi.nl with SMTP id AA29781 (5.65b/3.11/CWI-Amsterdam); Thu, 14 Oct 1993 17:31:09 +0100 Received: by ansjovis.cwi.nl with SMTP id AA19051 (5.65b/3.8/CWI-Amsterdam); Thu, 14 Oct 1993 17:31:08 +0100 Message-Id: <9310141631.AA19051=sjoerd@ansjovis.cwi.nl> To: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Cc: python-list@cwi.nl Subject: Re: Killed In-Reply-To: Your message of Thu, 14 Oct 1993 12:21:36 -0400. <199310141621.AA13403@elvis.med.Virginia.EDU> Date: Thu, 14 Oct 1993 17:31:07 +0100 From: Sjoerd Mullender <Sjoerd.Mullender@cwi.nl> On Thu, Oct 14 1993 "Steven D. Majewski" wrote: > One of my python programs, after getting 80% into processing a > rather large file, responds with the terse message: > > Killed > > and exits. > > That's certainly not one of MY messages. > Maybe it's an OS message ( from IBM AIX 3.2.2 ) > Is there anyplace in the python code that might produce that message ? > > I expect it is a cryptic message from AIX, but I thought I'ld > check to see if anyone has ever seen anything similar. This message comes from the shell and is the signal which terminated your python process. The signal "Killed" (signal 9) is sent by the kernel if it notices that some resource (usually virtual memory) is unavailable. It is sent more or less at random to a process. Apart from making sure that your system doesn't get overloaded, there is nothing you can do about this. This particular signal cannot be caught or ignored. Sjoerd Mullender CWI, dept. CST, Kruislaan 413, 1098 SJ Amsterdam, Netherlands email: Sjoerd.Mullender@cwi.nl fax: +31 20 592 4199 phone: +31 20 592 4127 telex: 12571 mactr nl Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA01038 (5.65b/3.11/CWI-Amsterdam); Thu, 14 Oct 1993 19:12:57 +0100 To: python-list@cwi.nl Subject: INDEX from ftp.markv.com:/pub/python X-Organization: Mark V Systems Ltd. X-Address: 16400 Ventura Blvd Suite 303, Encino, Ca, 91436, USA X-Phone: +1 818 995 7671 (work), +1 818 995 4267 (fax) Date: Thu, 14 Oct 93 11:11:55 PDT From: lance@markv.com Sender: lance@markv.com Message-Id: <9310141111.aa06007@hermix.markv.com> Source-Info: From (or Sender) name not authenticated. Welcome to one of Python's FTP sites! In this directory you will find the latest version of Python as well as some documentation on it. You will also find some useful scripts and modules that are not part of the distribution. There is also a Python mailing list. To join, send a message to: python-list-request@cwi.nl The Python distribution is mirrored from: ftp.cwi.nl:/pub/python If you have any questions/comments/problems with any of the files listed, please contact the author directly. If you would like to post anything to this FTP site, please create a <whatever file>.readme file and then FTP all necessary files to ftp.markv.com:/incoming/python This directory is a "drop directory". You will not be able to see anything in that directory.. Then please drop me an Email and let me know it is there.. I will add it to this INDEX file and let everyone know. Thank you and enjoy! Lance Ellinghouse lance@markv.com Index of ftp.markv.com:/pub/python Files: python0.9.9.tar.gz Author: Guido.van.Rossum@cwi.nl Description: Python distribution version 0.9.9 Files: pythondoc-ps0.9.9.tar.gz Author: Guido.van.Rossum@cwi.nl Description: PostScript documentation for Python distribution version 0.9.9 Files: Dates.py Dates.readme Author: Tim Peters <tim@ksr.com> Description: Date manipulation class See Dates.readme and Dates.py for more info.. Replied: Thu, 14 Oct 1993 19:26:52 +0100 Replied: ""Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> " Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA01133 (5.65b/3.11/CWI-Amsterdam); Thu, 14 Oct 1993 19:22:48 +0100 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa02157; 14 Oct 93 14:22 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA14545; Thu, 14 Oct 1993 14:22:23 -0400 Date: Thu, 14 Oct 1993 14:22:23 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199310141822.AA14545@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: python-list@cwi.nl Subject: Re: Killed Thanks everyone! I thought it *looked* more like a unix shell message - that terse single word with no other explaination: 'Killed' ! None of the machine limits looked likely, and since it seemed to happen in the same point in the file, I managed to 'manually' restart it near that point, and after a pause in the output stream occurred, I hit ^C - where upon I got several pages of stack trace from python indicating that I have a *slight* recursion-gone-wild bug in my python code. Another tribute to the benefits of interactive programming: not only had I THOUGHT that my code had been pretty well tested, but it successfully ran on about 200,000 blocks of a 300,000 block file, before it ran into the "right" test case. It WOULD have been nicer if Python could have intercepted the problem and given me a nicer message, without having had to force the stack dump with ^C ( i.e. at that point, I had already sort of guessed what the problem must be, and was looking for the where. ) but from the replies I got, it looks like there is nothing Python can do about catching the Kill signal. [ fodder for one of the comp.unix news groups: should unix first try signaling with a "catchable" signal before trying the final irrevokable kill ? i.e. "STOP WHATEVER YOU"RE DOING", ... "NO - I *REALLY* MEAN IT!" I mean, that *IS* the typical mode of parent/child interaction! Isn't it? ;-) ] - Steve M. Received: from boulder.Colorado.EDU by charon.cwi.nl with SMTP id AA01454 (5.65b/3.11/CWI-Amsterdam); Thu, 14 Oct 1993 19:49:11 +0100 Received: from vette.Colorado.EDU by boulder.Colorado.EDU with SMTP id AA22998 (5.65c/IDA-1.4.4 for <@boulder.colorado.edu:python-list@cwi.nl>); Thu, 14 Oct 1993 12:49:05 -0600 Received: by vette.colorado.edu (920330.SGI/911001.SGI) for @boulder.colorado.edu:python-list@cwi.nl id AA21685; Thu, 14 Oct 93 12:49:04 -0600 Date: Thu, 14 Oct 93 12:49:04 -0600 From: michel@vette.colorado.edu (Michel Lesoinne) Message-Id: <9310141849.AA21685@vette.colorado.edu> To: python-list@cwi.nl Subject: Termcap /curses Is it possible to use termcap and or curses on python ? Has anybody done it, or should I make my own extension to python ? Michel Replied: Fri, 15 Oct 1993 10:16:30 +0100 Replied: "python-list " Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA01691 (5.65b/3.11/CWI-Amsterdam); Thu, 14 Oct 1993 20:10:24 +0100 To: michel@vette.colorado.edu Cc: python-list@cwi.nl In-Reply-To: <9310141849.AA21685@vette.colorado.edu> (message from Michel Lesoinne on Thu, 14 Oct 93 12:49:04 -0600) Subject: Re: Termcap /curses X-Organization: Mark V Systems Ltd. X-Address: 16400 Ventura Blvd Suite 303, Encino, Ca, 91436, USA X-Phone: +1 818 995 7671 (work), +1 818 995 4267 (fax) Date: Thu, 14 Oct 93 12:09:09 PDT From: lance@markv.com Sender: lance@markv.com Message-Id: <9310141209.aa13155@hermix.markv.com> Source-Info: From (or Sender) name not authenticated. > Is it possible to use termcap and or curses on python ? Currently there is no termcap or curses module for python > Has anybody done it, or should I make my own extension to python ? I need one also.. I was thinking of making it myself.. just have not had the time. I would be happy to help if I can.. -- Lance Ellinghouse lance@markv.com 1231 bit key fingerprint = 56 DA 31 0C 17 51 36 6A 4E D4 E0 11 D9 B8 06 0A 1024 bit key fingerprint = 66 2C 75 F2 E9 1C 32 84 3A E3 B0 5E 48 01 4C 37 You can receive my Public Key by `finger lance@markv.com` Received: from boring.cwi.nl by charon.cwi.nl with SMTP id AA02451 (5.65b/3.11/CWI-Amsterdam); Thu, 14 Oct 1993 21:26:48 +0100 Received: by boring.cwi.nl id AA10840 (4.1/2.10/CWI-Amsterdam); Thu, 14 Oct 93 21:26:48 +0100 Date: Thu, 14 Oct 93 21:26:48 +0100 From: Dik.Winter@cwi.nl Message-Id: <9310142026.AA10840.dik@boring.cwi.nl> To: python-list@cwi.nl Subject: Re: Killed The base problem is with AIX which does lazy allocation of resources (memory in special). I.e. "malloc" always succeeds! There appears to be in later versions of AIX a version of "malloc" which actually tells whether it did succeed or not. dik Forwarded: Wed, 03 Nov 1993 16:08:30 +0100 Forwarded: "jredford@lehman.com " Replied: Fri, 15 Oct 1993 11:45:32 +0100 Replied: "Bill Janssen <janssen@parc.xerox.com> " Replied: Fri, 15 Oct 1993 10:51:35 +0100 Replied: "Bill Janssen <janssen@parc.xerox.com> " Received: from alpha.Xerox.COM by charon.cwi.nl with SMTP id AA04995 (5.65b/3.11/CWI-Amsterdam); Fri, 15 Oct 1993 01:02:33 +0100 Received: from holmes.parc.xerox.com ([13.1.100.162]) by alpha.xerox.com with SMTP id <11786>; Thu, 14 Oct 1993 17:02:02 PDT Received: by holmes.parc.xerox.com id <16134>; Thu, 14 Oct 1993 17:01:59 -0700 Received: from Messages.7.15.N.CUILIB.3.45.SNAP.NOT.LINKED.holmes.parc.xerox.com.sun4.41 via MS.5.6.holmes.parc.xerox.com.sun4_41; Thu, 14 Oct 1993 17:01:45 -0700 (PDT) Message-Id: <sgjSVd4B0KGWNDk0Zx@holmes.parc.xerox.com> Date: Thu, 14 Oct 1993 17:01:45 PDT Sender: Bill Janssen <janssen@parc.xerox.com> From: Bill Janssen <janssen@parc.xerox.com> To: python-list@cwi.nl Subject: Python & Sun shared libraries Denis Severson and I tried modifying Python to use the SunOS dynamic linking, and shared libraries. Seems to work just fine. Here are the diffs (from the 0.9.9 sources) for import.c (the only file which needed to change): *** import.c-dist Wed Oct 13 16:45:54 1993 --- import.c Wed Oct 13 17:40:27 1993 *************** *** 47,53 **** --- 47,58 ---- #endif #ifdef USE_DL + #ifdef SUN_SHLIB + #include <dlfcn.h> + typedef void (*dl_funcptr)(); + #else #include "dl.h" + #endif /* SUN_SHLIB */ extern char *argv0; #endif *************** *** 98,104 **** --- 103,113 ---- #define PY_SUFFIX ".py" #ifdef USE_DL + #ifdef SUN_SHLIB + #define O_SUFFIX "module.so" + #else #define O_SUFFIX "module.o" + #endif /* SUN_SHLIB */ #endif /* Find and open a module file, using sys.path. *************** *** 183,189 **** --- 192,205 ---- dl_funcptr p; D(fprintf(stderr, "Found %s\n", namebuf)); sprintf(funcname, "init%s", name); + #ifdef SUN_SHLIB + { + void *handle = dlopen (namebuf, 1); + p = (dl_funcptr) dlsym(handle, funcname); + } + #else p = dl_loadmod(argv0, namebuf, funcname); + #endif /* SUN_SHLIB */ if (p == NULL) { D(fprintf(stderr, "dl_loadmod failed\n")); } To link python dynamically under SunOS, just remove the -Bstatic flag when linking, and define the SUN_SHLIB flag when compiling import.c. To create a new object module that is capable of being dynamically loaded, type "ld -o foomodule.so foomodule.c". Note the ".so" suffix. I'd really like to be able to move stdwin to a dynamically loaded object module, but there is stdwin-specific code in config.c which makes some initialization and finalization calls to the STDWIN library. Could that code be moved/replaced? Bill Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA12526 (5.65b/3.11/CWI-Amsterdam); Fri, 15 Oct 1993 10:16:31 +0100 Received: by voorn.cwi.nl with SMTP id AA09011 (5.65b/3.8/CWI-Amsterdam); Fri, 15 Oct 1993 10:16:31 +0100 Message-Id: <9310150916.AA09011=guido@voorn.cwi.nl> To: python-list@cwi.nl Subject: Re: Termcap /curses In-Reply-To: Your message of "Thu, 14 Oct 1993 12:09:09 MDT." <9310141209.aa13155@hermix.markv.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Fri, 15 Oct 1993 10:16:30 +0100 Sender: Guido.van.Rossum@cwi.nl > > Is it possible to use termcap and or curses on python ? > > Currently there is no termcap or curses module for python > > > Has anybody done it, or should I make my own extension to python ? > > I need one also.. I was thinking of making it myself.. just have > not had the time. I would be happy to help if I can.. Note that in principle you could do it all in Python -- with the (optional) fcntl module you can make the necessary ioctl calls and then just read the termcap file and generate the proper calls. Alternatively, there's a "character-cell device" version of STDWIN (the "alfa" port) which uses termcap. It is line oriented but has the advantage of making the transition from a termcap application to a windowing application relly smooth... --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA21331 (5.65b/3.11/CWI-Amsterdam); Fri, 15 Oct 1993 17:56:55 +0100 Received: from [138.95.9.34] by gateway.sequent.com (5.61/1.34) id AA04999; Fri, 15 Oct 93 09:57:30 -0700 Received: from ushqgw1.sequent.com by relay1.sequent.com (5.65/crg/11) id AA27066; Fri, 15 Oct 93 09:57:05 -0700 Received: by ushqgw.sequent.com with Microsoft Mail id <2CBED431@ushqgw.sequent.com>; Fri, 15 Oct 93 09:47:45 PDT From: "Jaap Vermeulen (jaap)" <jaap@sequent.com> To: guido <guido@cwi.nl>, python-list <python-list@cwi.nl> Subject: Re: Termcap /curses Date: Fri, 15 Oct 93 09:47:00 PDT Message-Id: <2CBED431@ushqgw.sequent.com> Encoding: 12 TEXT X-Mailer: Microsoft Mail V3.0 | Note that in principle you could do it all in Python -- with the | (optional) fcntl module you can make the necessary ioctl calls and | then just read the termcap file and generate the proper calls. You would have to re-implement the mapping from generic terminfo/termcap strings to actual escape sequences including padding; reimplement some form of curses etc. etc. Not that it couldn't be done, but I think you're getting into more than you ever bargained for... -Jaap- Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA21758 (5.65b/3.11/CWI-Amsterdam); Fri, 15 Oct 1993 18:24:24 +0100 To: jaap@sequent.com Cc: guido@cwi.nl, python-list@cwi.nl In-Reply-To: <2CBED431@ushqgw.sequent.com> (jaap@sequent.com) Subject: Re: Termcap /curses X-Organization: Mark V Systems Ltd. X-Address: 16400 Ventura Blvd Suite 303, Encino, Ca, 91436, USA X-Phone: +1 818 995 7671 (work), +1 818 995 4267 (fax) Date: Fri, 15 Oct 93 10:23:02 PDT From: lance@markv.com Sender: lance@markv.com Message-Id: <9310151023.aa18159@hermix.markv.com> Source-Info: From (or Sender) name not authenticated. > | Note that in principle you could do it all in Python -- with the > | (optional) fcntl module you can make the necessary ioctl calls and > | then just read the termcap file and generate the proper calls. > > You would have to re-implement the mapping from generic terminfo/termcap > strings to actual escape sequences including padding; reimplement some form > of curses etc. Not that it couldn't be done, but I think you're getting > into more than you ever bargained for... Not only this, but the curses packages also take into account terminals that have strange behavior.. I can see a LOT of recoding trying to make a PYTHON version of curses instead of just creating an interface to it.. Also, by recreating a python version, I would not have any of the menu and form libraries available that come with my curses libraries.. -- Lance Ellinghouse lance@markv.com 1231 bit key fingerprint = 56 DA 31 0C 17 51 36 6A 4E D4 E0 11 D9 B8 06 0A 1024 bit key fingerprint = 66 2C 75 F2 E9 1C 32 84 3A E3 B0 5E 48 01 4C 37 You can receive my Public Key by `finger lance@markv.com` Received: from uunet.ca by charon.cwi.nl with SMTP id AA22215 (5.65b/3.11/CWI-Amsterdam); Fri, 15 Oct 1993 19:05:58 +0100 Received: from tsltor by mail.uunet.ca with UUCP id <102122(5)>; Fri, 15 Oct 1993 14:05:44 -0400 Received: from osprey.teleride.on.ca by falcon.teleride.on.ca with smtp (Smail3.1.26.7 #5) id m0ontVz-0000eOC; Fri, 15 Oct 93 14:04 EDT Received: by vax.teleride.on.ca (MX V3.0A) id 31251; Fri, 15 Oct 1993 14:02:34 EDT Sender: <lou@VAX.TELERIDE.ON.CA> Date: Fri, 15 Oct 1993 14:02:41 -0400 From: Lou Kates <lou@VAX.TELERIDE.ON.CA> To: python-list@cwi.nl Message-Id: <009740EC.69AFD6A0.31251@vax.teleride.on.ca> Subject: Re: Termcap /curses > > | Note that in principle you could do it all in Python -- with the > > | (optional) fcntl module you can make the necessary ioctl calls and > > | then just read the termcap file and generate the proper calls. > > > > You would have to re-implement the mapping from generic terminfo/termcap > > strings to actual escape sequences including padding; reimplement some form > > of curses etc. Not that it couldn't be done, but I think you're getting > > into more than you ever bargained for... > > Not only this, but the curses packages also take into account terminals >that have strange behavior.. I can see a LOT of recoding trying to >make a PYTHON version of curses instead of just creating an interface to >it.. Also, by recreating a python version, I would not have >any of the menu and form libraries available that come with my >curses libraries.. > Another approach would be to develop a C to Python translator. That would also be a large amount of work and its conceivable that certain features would have to be added to Python to make it feasible but it would allow one to translate not only the bulk of the curses source but many other C libraries all in one go. Lou Kates, louk@teleride.on.ca Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA22512 (5.65b/3.11/CWI-Amsterdam); Fri, 15 Oct 1993 19:37:50 +0100 Received: from [138.95.9.34] by gateway.sequent.com (5.61/1.34) id AA09442; Fri, 15 Oct 93 11:38:26 -0700 Received: from ushqgw1.sequent.com by relay1.sequent.com (5.65/crg/11) id AA00535; Fri, 15 Oct 93 11:46:35 -0700 Received: by ushqgw.sequent.com with Microsoft Mail id <2CBEEDDB@ushqgw.sequent.com>; Fri, 15 Oct 93 11:37:15 PDT From: "Jaap Vermeulen (jaap)" <jaap@sequent.com> To: python-list <python-list@cwi.nl>, lou <tsltor!vax.teleride.on.ca!lou@mail.uunet.ca> Subject: Re: Termcap /curses Date: Fri, 15 Oct 93 11:33:00 PDT Message-Id: <2CBEEDDB@ushqgw.sequent.com> Encoding: 14 TEXT X-Mailer: Microsoft Mail V3.0 | Another approach would be to develop a C to Python translator. | That would also be a large amount of work and its conceivable | that certain features would have to be added to Python to make it | feasible but it would allow one to translate not only the bulk of | the curses source but many other C libraries all in one go. I'm afraid that you would lose the object oriented aspect of Python, which is the most valuable aspect of Python modules that interact with certain facets of POSIX. As an example look at the socket module. If the translation does not allow this kind of abstraction, it would be useless IMHO. -Jaap- Replied: Mon, 18 Oct 1993 21:26:49 +0100 Replied: "tb06@PL122e.EECS.Lehigh.EDU (TERRENCE BRANNON) " Received: from pl122e.eecs.lehigh.edu by charon.cwi.nl with SMTP id AA22897 (5.65b/3.11/CWI-Amsterdam); Fri, 15 Oct 1993 20:14:22 +0100 Received: by PL122e.EECS.Lehigh.EDU (5.61/1.34) id AA00535; Fri, 15 Oct 93 15:01:32 -0400 Date: Fri, 15 Oct 93 15:01:32 -0400 From: tb06@PL122e.EECS.Lehigh.EDU (TERRENCE BRANNON) Message-Id: <9310151901.AA00535@PL122e.EECS.Lehigh.EDU> To: python-list@cwi.nl Subject: [request] Impressive Python Software I am getting ready to post another copy of my paper: "Survey of Quick Interpreted Languages" to Usenet. However, before I do so, I would like to know what impressive software has been developed with Python. I am including a Beta copy of my paper. Note the chapter "Significant software" Terrence Brannon ...... tb06@pl122e.eecs.lehigh.edu Address ............... PO Box 5027, Bethelehem, PA 18015 Phone ................. 215-758-4081. 215-758-0780 \documentstyle{report} \pagestyle{headings} \begin{document} \title { Survey of Quick Interpreted Languages } \author { Terrence Monroe Brannon \\ PO Box 5027 \\ Bethlehem, PA 18015 \\ $tb06@pl122e.eecs.lehigh.edu$ } \maketitle \tableofcontents %%% 1. \part {Introduction} %%% \part {Introduction} The purpose of this FAQ is to expose people to several languages which can cutdown/eliminate shell programming and C programming. All of these languages are quick interpreted languages which can do things in a few lines which might take hundreds of lines of C/shell code. These languages are evaluated in terms of the three things that any programmer desires from a language: power, speed, and ease of use. Power means a wealth of libraries for any task needed. Speed needs no explanation. Ease of use includes how well documented the language is, how much support there is for problems with the language, and how cleanly extensible the language is. \section {The Languages} \begin{description} \item[Scheme: Elk version] Elk is a Scheme interpreter intended to be used as a general, reusable extension language subsystem for integration into existing and future applications. Elk can also be used as a stand-alone implementation of the Scheme programming language. One purpose of the Elk project is to end the recent proliferation of mutually incompatible Lisp-like extension languages. Instead of inventing and implementing yet another extension language, application programmers can integrate Elk into their application to make it extensible and highly customizable. The Elk project was started in 1987 to support ISOTEXT, an ODA-based document system (a WYSIWYG editor) that is being developed at the Technical University of Berlin. Elk has been successfully demonstrated as the extension language kernel of ISOTEXT, e.g. at the Hanover Fair 1989. We feel that Scheme is better suited as a general extension language than other Lisp dialects: it is sufficiently small to not dwarf the application it serves and to be fully understood with acceptable effort; it is orthogonal and well-defined. In addition, Scheme has been recognized to be mature enough for national and international standardization (IEEE P1178, ISO/IEC JTC1/SC22/WG16). The Elk Scheme implementation is R4RS and P1178 conforming (with the exception of the number system and a few other details that are listed in the documentation). Elk supports several additional language features to increase its usability as an extension language, among them dynamic, incremental loading of object files and `freezing' of a fully customized application into a new executable file (`dump'). Other additional features of the Scheme implementation are: \begin{itemize} \item a simple macro facility \item environments as first-class objects \item dynamic-wind, fluid-let \item autoloading, provide/require \end{itemize} The current release of Elk includes several dynamically-loadable extensions, among them interfaces to the X11 Xlib and to the application programmer interface of the Xt intrinsics, and interfaces to the Athena and OSF/Motif widget sets. As an alternative to the stop-and-copy garbage collector provided with earlier versions of Elk, the Scheme interpreter now supports a generational, incremental garbage collector. The generational garbage collector is more efficient and thus reduces the time the application is disrupted by a garbage collection. On platforms supporting advanced memory management, the garbage collector can be switched to `incremental' mode, further reducing wait times. \item {Lisp: Emacs version} Anything Emacs does is done in Lisp, so you can do it to. This means you can have automatic completion of input, full screen editing, buffering routines and much more. But you can only do it inside of Emacs Lisp for the most part. The two work arounds are: (1) use emacs-server.el which allows Emacs to send/receive onsockets (2) use emacs server mode. (3) I am currently working on extracting the interpreter from Emacs so that it is callable from C. Emacs' only interaction with other programs is through its batch mode which is callable from C or shell scripts. C programs cannot use Emacs routines and Emacs cannot call C. Emacs can call shell scripts and supply command line arguments as well. \item[Perl] Combines the best features of awk, sed, and shell programming. The latest version can be embedded in C programs. It is also easy to call from the shell. The embeddable version, which is perl5, is not yet out for public release quite yet. I would say that you should include C as "the best features" of list, since one of its strong points is easy access to unix syscalls and C library features. Perl can be linked with external C libraries, such as curses or database accessing libraries, like oracle or sybase, making for easy access to screen-based form programs to deal with your dbase. The Wafe server lets you get at X from perl. \item[Python] An object-oriented interpreted language. Callable from C as well as the shell. Interpretation may be sidestepped through the use of the byte-compiler on files. Python played a major role in testing Amoeba, a distributed operating system developed at CWI. \item[Tcl] Extremely strong in X-windows. It can do a 5 page x-windows program in *2* lines and more. Callable from C and from the shell. \end{description} \section{Obtaining} All of these packages are publicly available via ftp. I have chosen the ange-ftp method of representing ftp connections for its conciseness. The following: "/anonymous@src.doc.ic.ac.uk:/pub/gnu" means make an anonymous ftp connection to src.doc.ic.ac.uk then cd to /pub/gnu. As a side note, if you had Hyperbole (an Emacs-based hypertext package) installed and running under X-Windows, you could just click on the quotation-mark-enclosed pathname above and you would automatically be connected to the above directory. All documentation and source code have their copyright status with the distribution. Consult the distribution for information on using these products as part of your own creative work. \begin{description} \item[Emacs Lisp] "/anonymous@src.doc.ic.ac.uk:/pub/gnu" "/anonymous@prep.ai.mit.edu:/pub/gnu" \item[Perl] "/anonymous@convex.com:/pub/perl" "/anonymous@archive.cs.ruu.nl:/DOC" \item[Python] "/anonymous@ftp.cwi.nl:/pub" \item[Tcl] "/anonymous@ftp.uu.net:/languages/tcl" "/anonymous@barkley.berkeley.edu:/tcl" \end{description} \section{The Future} \begin{itemize} \item Emacs Lisp does not have object-oriented extensions yet Python does. Python does not yet have a robust ftp interface like Emacs' ange-ftp nor does it have an advanced desk top calculator like Emacs's calc. However it does have STDWIN, an easy-to-use windowing system. Expression of mathematics in Tcl is cumbersome yet X11 graphics is very very easy. Perl has excellent string and manipulation tools and a ton of sysadmin utilities written in it. The bottom line is that all of these languages have powerful tools ready to use. Each language also has its weak points. Instead of being stuck in each language and slaving through its weakness (or lack of a certain utility), one should be able to fire up an interpreter in any of these other languages and let it perform on it strong points and return the answer. I expect this type of hybrid programming to become almost necessary with excellent packages and large being written for each langauge. \item I am currently working on socketed interprocess communication between a Python interpreter and Emacs Lisp. Next will be Tcl. Perhaps next will be postscript or maybe Perl. \item A trans-language browser. If you see that a Perl script has been written to traverse a directory tree and count the number of files ending in .o whose age is more than 20 days but you are not a Perl programmer, that Perl script should become and OBJECT to which you SEND a message to get that work done. \end{itemize} %%% 2. \part {Power} %%% \part {Power} %%% 2.1. \chapter {Significant Software} %%% \chapter {Significant Software} An important feature of these languages is how much is already there for you to use. %%% 2.1.1. \section {Emacs Lisp} %%% \section {Emacs Lisp} \begin{description} \item[Folding Mode] Allows for hierarchical editing of structured text files. I use it all the time. You can move through and edit any document (program, LaTeX file, whatever) much faster using folding mode. \item[VM] A mail reader that does everything that I need. \item[Gnus] A Usenet reader that can save articles to mail folders for later recall. I often save articles in Gnus and later read them using VM. \item[EDB] full featured database \item[Ange-FTP] An excellent ftp utility which allows transparent file access/modification with the ease of a few keystrokes. \item[user interfaces] Countless interfaces for everything from Archie to MUD role playing games. \item[AUC-TeX] Allows you to do anything you would want to do with TeX/LaTeX from an Emacs buffer quickly and easily. \item[Calc] The poor man's Mathematica. Includes rewrite rules and functionality on the order of the HP-28. \item[VIP] vi emulation for emacs \item[Calendar/Diary] Calendar and appointment manager within Emacs \item[Tree Dired] Allows you to scroll through directories and copy, edit, remove, view files. And more \item[Hyperbole] Extensible hypertext management system within Emacs. \end{description} %%% 2.1.2. \section {Perl} %%% \section {Perl} Having been publicly available for six years now, Perl has a truly huge body of code already written for it. I couldn't begin to document all of them. More than any other language listed herein, it is the tool of choice for Unix system administrators. Perl comes with a symbolic debugger, a bunch of libraries, various tools, and and numerous example programs, but that's just the start. %%% 2.1.3. \section {Python} %%% \section {Python} \begin{enumerate} \item ?? -- Multimedia interface. \item ?? -- Remote Procedure Call debugger \item texfix -- Crude convert latex to texinfo \item throughput -- measure tcp throughput \item dutree -- format du(1) output at a tree sorted by size \item findlinks -- recursively find links to a given path prefix \item lpwatch -- watch BSD line printer queues \item suff -- sort a list of files by suffix \end{enumerate} %%% 2.1.4. \section {Tcl} %%% \section {Tcl} \begin{enumerate} \item[Tcl-DP] Layered distributed computing for Tcl. Tcl-DP adds TCP and IP connection management, remote procedure call (RPC), and distributed object support to Tcl \item[Extended TCL] Adds keyed lists, a debugger and profiler and the full suite of Unix process control primitives to Tcl. \item[Objectify] Turns C++ classes into Tcl objects. \item[Artcls] A graphic Usenet newsreader. \item[TkWWW] A Tk world-wide web browser. \item[XF] An X11 user interface builder \item[WAFE] {\it W}idget {\it A}thena {\it F}ront {\it E}nd. Implemented in Tcl, this package allows for the same generic graphic commands to be used to develop user interfaces regardless of what language you are programming in. All you need to do is interface to WAFE from your language. \item[PhotoWidget] A photo widget for Tk. \item[TSipp] A Tcl interface to the SIPP 3-D rendering library. \item[TkSteal] Allows for a Tk program to have an Emacs widget or a Ghostscript widget. \item[Pixmap] A color pixmap editor written in Tcl/Tk \item[VOGLE] Awesome full-color 3-D rendering package with a ton of fonts, both american and foreign. \end{enumerate} %%% 2.2. \chapter {Graphics} %%% \chapter {Graphics} \section{Emacs Lisp} None internally, but the ability to spawn inferior unix processes and issue shell commands allows it to use tcl's WAFE or fire up a Python process and control it with ease. \section{Perl} Again none interally, but the author of WAFE, the tcl/tk graphic interpreter wrote all of his example programs in Perl (wafemail, wafenews, wafeftp). Certainly perl can issue external commands (inferior processes in lisp parlance). There is also a version of guiperl I've seen Larry demo for me, so there's at least proof-of-concept that you can link in the X libs. Whether it will come out with perl5 I don't know. \section{Python} Through the use of the STDWIN paradigm, the same source code can do graphics in the following systems: \begin{enumerate} \item X-windows \item Macintosh using either Think C 4.02 or MPW C 2.02 \item Atari ST \item DOS \item Silicon Graphics SGI workstations \end{enumerate} This approach allows flexibility but means that no one graphics system's potential is maximized. \section{Tcl} Overloaded with all types of very very easy to do attractive graphics in X-Windows only. Easy to learn, and has many nice widgets added to it such as a photo widget for display of scanned PBM images, a bar graph widget, an editable text widget and much more. Powerful tcl-based graphics systems come to mind: \begin{enumerate} \item xy-graph - includes a Hypertext widget. This means that regardless of what stream of information comes at your Tcl program, you can create windows and paths through the stream on the fly. A major example of the hypertext widget is Joseph Wang's World Wide Web Hypertext browser. \item VOGLE - 3D rendering, fonts \item BYO Interface Builder. A snap to use. \item XF - Another interface builder by the developers of TkEmacs. Arguably as good as BYO. \item WAFE . Send text string from anywhere (C language, Emacs, shell) to a server and have the graphics done for you. \item BOS - An object oriented extension for Tcl which also has some widgets added to it. \end{enumerate} %%% 2.3. \chapter {User Interface Building} %%% \chapter {User Interface Building} \section{Emacs Lisp} None internally, but the ability to spawn inferior unix processes and issue shell commands allows it to use tcl's WAFE or fire up a Python process and control it with ease. \section{Perl} Again none interally, but the author of WAFE, the tcl/tk graphic interpreter wrote all of his example programs in Perl (wafemail, wafenews, wafeftp). Certainly perl can issue external commands (inferior processes in lisp parlance). There is also a version of guiperl I've seen Larry demo for me, so there's at least proof-of-concept that you can link in the X libs. Whether it will come out with perl5 I don't know. \section{Python} Through the use of the STDWIN paradigm, the same source code can do graphics in the following systems: \begin{enumerate} \item X-windows \item Macintosh using either Think C 4.02 or MPW C 2.02 \item Atari ST \item DOS \item Silicon Graphics SGI workstations \end{enumerate} This approach allows flexibility but means that no one graphics system's potential is maximized. \section{Tcl} Overloaded with all types of very very easy to do attractive graphics in X-Windows only. Easy to learn, and has many nice widgets added to it such as a photo widget for display of scanned PBM images, a bar graph widget, an editable text widget and much more. Powerful tcl-based graphics systems come to mind: \begin{enumerate} \item xy-graph - includes a Hypertext widget. This means that regardless of what stream of information comes at your Tcl program, you can create windows and paths through the stream on the fly. A major example of the hypertext widget is Joseph Wang's World Wide Web Hypertext browser. \item VOGLE - 3D rendering, fonts \item BYO Interface Builder. A snap to use. \item XF - Another interface builder by the developers of TkEmacs. Arguably as good as BYO. \item WAFE . Send text string from anywhere (C language, Emacs, shell) to a server and have the graphics done for you. \item BOS - An object oriented extension for Tcl which also has some widgets added to it. \end{enumerate} %%% 2.4. \chapter {String Handling} %%% \chapter {String Handling} \section{Emacs Lisp} Strong. Many good string handling functions for operation on buffers as well as string. Search replace backward and forward with regexps. Many good string handling functions are found in tree-dired.el in gmhist*.el. As well as in ange-ftp.el. \section{Perl} Very strong. String-handling is one of Perl's strongest features: they are quite powerful and extensive. Strings can be as long as you want, and contain binary data and nulls. This works: \begin{verbatim} $kernel = `cat /vmunix`; \end{verbatim} Perl has a wealth of string-accessing functions, including matching, substitution, transliteration, splitting, and direct substring accessing. Strings and numbers are interchangeable. The regexps are a superset of other regexp syntaxes, with extensions. Parsing is very easy: \begin{verbatim} ($name, $number, $host) = /(\w+)=(\d+)( from @(\w+))?/; \end{verbatim} Subexpressions can nest, and be arbitrarily deep: you don't have to stop with \\9, but can keep going. Perl's substitution operator works like sed's: \begin{verbatim} s/foo/bar; \end{verbatim} or \begin{verbatim} $a =~ s/foo/bar/g; \end{verbatim} but can do much more, like: \begin{verbatim} s/(\d+)/sprintf("0x%08x", $1)/ge; \end{verbatim} to find all the numbers in the pattern space and replace them with the hex representation of the same. It has other powerful features I don't have time or space to go into. Perl also lets you treat strings as raw bitwise data, so \begin{verbatim} substr($a,0,3) &= "\177\177\177"; \end{verbatim} would clear the high bits on the first 3 bytes of \$a. You can also access strings bitwise, say, to check the $2456$th bit of a string. \section{Python} It has a string module and regexp module. It has all the string @emph{search} capabilities of Emacs, but since strings are immutable in Python, it understandably does not have Emacs Lisp's string replace power. \section{Tcl} Everything in Tcl is a string. It is very easy to map certain string-intensive applications to Tcl. For example, I wrote a program to do parallel library database searches in Tcl in about two weeks. Ranking the 4 languages in terms of how easy it would have been: Tcl, Python, Emacs, and I cant say about Perl because I gave up on Perl quickly after buying the book and seeing all those registers and the confusing context-intensive syntax. %%% 2.5. \chapter {Process Control} %%% \chapter {Process Control} \section {Emacs Lisp} Has specialized modes for controlling Common and other lisps to facilitate debugging, execution, and programming. Has shell modes with command history. Has an excellent ftp program (ange-ftp). Can asynchronously or synchronously call the shell and store the output in a buffer or string. Can filter output from a process. However, the filtering is somewhat hairy because you cannot be sure of the packet size that the data will arrive in. In other words, it is easy to open a pipe with Perl/Python/Tcl and just read lines at a time but you have to write an accumulator function to do this in Emacs Lisp. However, the interactor mode for GNU Smalltalk has an excellent accumulator function that you could use in your own code. \section{Perl} Perl has all the process control primitives available to you from C, plus higher level constructs as well. It's easy to open a pipe to or from another process. You can even open a pipe to an implicitly forked version of yourself. Standard Perl library routines allow bidirectional pipes and running things over a pty via a package that works much like Don Libes's Expect, save that it uses Perl instead of tcl as an extension language. Perl can also access all the socket and ipc functions on your system without calling a program to do it. \section{Python} You would use pipes to do this in Python. \section{Tcl} Even stronger than Emacs. A package by Don Libes called Expect allows the programmer to specify a set of expected regexps from the process and what to do upon the receipt of the process output. Several of his papers including "expect: Curing Those Uncontrollable Fits of Interaction" available in postscript format for anonymous ftp from durer.cme.nist.giv in pub/expect. There are also numerous process control extensions in Extended Tcl, which will be detailed in the section titled extensions. %%% 2.6. \chapter {Sample Programs} %%% \chapter {Sample Programs} To give you a taste of how each of these languages does its thing, I have created some simple programs to give you an idea of how easy each language can do some routine tasks. None of the programs have been written for any of the languages for this version of the FAQ. If you would like to contribute source, feel free. Or if you have a program done in one of these languages that you think would have been very difficult in one of the others let me know. The programs are: \begin{enumerate} \item Write a program to count the number of files in the current directory. \section{Emacs Lisp} \begin{verbatim} (defun current-directory-size () ``Number of files in the current directory.'' (length (directory-files ``.'')) \end{verbatim} \section{Perl} \begin{verbatim} #!/usr/bin/perl $count = @files = <*>; print "Directory file count: $count\n"; #!/usr/bin/perl $count++ while <*>; print "Directory file count: $count\n"; #!/usr/bin/perl print "Directory file count:", `ls | wc -l`; # those didn't have dot files. if you want dot files, # use <* .*> instead. #!/usr/bin/perl opendir(DOT, '.'); $count = @files = readdir(DOT); print "Directory file count: $count\n"; #!/usr/bin/perl opendir(DOT, '.'); $count++ while readdir(DOT); print "Directory file count: $count\n"; \end{verbatim} \section{Tcl} \begin{verbatim} set count [ls | wc -l] \end{verbatim} \item Write a program to run under X-Windows and Macintosh which opens a window and prints {\tt "Hello, World"} in it. \section{Emacs Lisp} \begin{verbatim} (defun hello-world () ; FSF Emacs 19 only. ``Open new frame with a friendly greeting.'' (switch-to-buffer-other-frame ``*hello world*'') (insert ``Hello, World'')) \end{verbatim} \section{Perl} \begin{verbatim} I'd just talk to Wafe or Stdwin. Or call xterm. :-) \end{verbatim} \section{Tcl} \begin{verbatim} button .hello -text {Hello, World} -command {exit} pack append . .hello {top} \end{verbatim} %--------------------------------------------------------------- \item Given a file with 4 occurrences of the string "Hello Bob" find the file, replace the last 3 occurrences of "Hello Bob" with "Hi James" and save the file. The double quotation marks are for delineation purposes only. \section{Emacs Lisp} \begin{verbatim} (defun Bob-meet-James (file) ``Replace all `Hello Bob' with `Hi James' in FILE except the first.'' (save-excursion (find-file file) (goto-char (point-min)) ; We might already be editing it... (search-forward ``Hello Bob'') (while (search-forward ``Hello Bob'' nil t) (replace-match ``Hi James'')) (save-buffer))) \end{verbatim} \section{Perl} \begin{verbatim} # the orig file will be in file.BAK -- if you don't want a backup, # use just -i. # remember that s//foo/ will match the last match perl -i.BAK -p -e '/Hello Bob/ && $seen++ && s//Hi James/g' or perl thisprog < file.in > file.out #!/usr/bin/perl while (<>) { if (/Hello Bob/ && $seen++) { s//Hi James/g; } print; } \end{verbatim} \section{Tcl} \begin{verbatim} set fdIn [open testFile r] set contents [read $fdIn] regexp -indices "Hello Bob" $contents matches regsub -all "Hello Bob" \ [string range $contents [expr [lindex $matches 1]+1] end] \ "Hi James" result close $fdIn set fdOut [open testFile w] puts $fdOut [string range $contents 0 [lindex $matches 1]]$result \ nonewline close $fdOut exit \end{verbatim} \item A lengthy file has been entered with records of the form: \begin{verbatim} <\n>NAME<\n>ADDRESS<\n>PHONE<\n>---------- \end{verbatim} where \begin{verbatim}<\n>\end{verbatim} represents a line feed and the \begin{verbatim}----------- \end{verbatim} is used to separate records. Convert all entries in the file to a new format of the form: \begin{verbatim}<\n>NAME::ADDRESS::PHONE} \end{verbatim} \section{Emacs Lisp} \begin{verbatim} (defun newline-to-double-colon () ``Convert current buffer from old style to new style address book format.'' (goto-char (point-min)) (while (re-search-forward ``\n\\([^\n]*\\)\n\\([^\n]*\\)\n\\([^\n]*\\)\n----------'' nil t) (replace-match ``\n\\1::\\2::\\3''))) \end{verbatim} \section{Perl} \begin{verbatim} #!/usr/bin/perl $/ = "\n----------"; # set record separator while (<>) { # read a record s!$/$!!; # remove record terminator s/^\n//; # trim first line feed s/\n/::/g; # turn rest into double dolon print "\n"; # new record starts with \n print; # output current pattern space } # Did you know that the last record in the file will no longer # have a terminating newline? Make sure the others get this right. \end{verbatim} \section{Tcl} \begin{verbatim} set fdIn [open testFile r] set contents [read $fdIn] regsub -all "^\n" $contents "" contents regsub -all "\n" $contents "::" contents regsub -all "::----------::" $contents "\n" contents close $fdIn set fdOut [open testFile w] puts $fdOut $contents nonewline close $fdOut exit \end{verbatim} \end{enumerate} %%% 3. \part {Speed} %%% \part {Speed} %%% 4. \part {Ease of Use} %%% %%% 4.1. \chapter {Documentation/Support} %%% \chapter {Documentation/Support} \section{Emacs Lisp} Excellent. Both for using Emacs and programming Emacs Lisp. \section{Perl} Excellent. A book is out by Larry Wall called Programming in Perl. The manual page is 80 pages typeset. The newsgroup comp.lang.perl is very active and helpful and the newsgroup archives are available on-line, and come with literally thousands of code snippets and fully fledged programs doing more different things than I can begin to enumerate. There is also an excellent quick reference guide, and professionally-taught courses for Perl available. \section{Python} Good. Covers everything but how to extend Python through C. \section{Tcl} Good. The Tcl book is due out soon. \chapter{Program Development} \section{Emacs Lisp} The best. Has a debugger. Since you are in Emacs, you can immediately test whatever you are writing. Documentation on every function and variable in memory is available in 2 keypresses. The tags system allows you to jump to functions and global variable declarations without knowing which file they are in. \section{Perl} I would say strong. To use Perl, you only need to know a little bit to start to use it. The interactive debugger allows you to type any kind of Perl code you want and get an immediate answer, as well as providing standard sym debugger capabilities such as breakpoints, single-stepping, and stack tracebacks. Other tools available but not included with the Perl src kit include profilers, tags generators, cross referencers, and tools to assemble large Perl programs using makefiles and a lintlike checker. Other tools provide perl-mode for vi as well as tightly coupling the debugger with a slave vi session that autopositions by file and line. \section{Python} Good. The concept of immutable strings takes some getting used to. \section{Tcl} The language is very consistent --- every line is started with a command which is the name of a Tcl or C function. The rest of the line is arguments to the Tcl or C function. %%% 4.2. \chapter {Extensibility} %%% \chapter{Extensibility} When I say extensibility I mean the ability to add a new keyword or data type to a language as opposed to adding a new utility. \section{Emacs Lisp} Writing new lisp functions is only feasible by using the already-available lisp functions. To write new lisp functions in C would mean re-compiling Emacs every time. \section{Perl} You can extend Perl through linking with C routines. The example with the perl kit explains how to do this for the curses library, but can be done for many other applications as well. This is adding new function calls. What I don't think is easy is changing the perl syntax. What you would probably do is define a package and use acccessor functions. I did this to allow perl user's to get at C struct and union types to interract with C programs. A package is semi-reminiscent of a C++ class, perhaps best described as a protected namespace with private and public data declarations and initialization code, as well as both private and public functions. I wonder how the other languages stack up on this kind of thing. \section{Python} Its possible in C. How to do it in C is not well documented. \section{Tcl} Its possible and well-docuemented and has been down well by many people in C. \chapter{Test Suite} \section{Emacs Lisp} Well, if you compile Emacs then Emacs Lisp will run. This is irrelevant criteria for Emacs Lisp. \section{Perl} Perl comes with an exhaustive test suite. \section{Python} Exhaustive test suite \section{Tcl} Exhaustive test suite %%% 5. \part {The Future} %%% \part {The Future} \section {More Languages} \section {More Examples and Tests} \section {Multiple Computer Language Programming} \end{document} Received: from uunet.ca by charon.cwi.nl with SMTP id AA23047 (5.65b/3.11/CWI-Amsterdam); Fri, 15 Oct 1993 20:35:22 +0100 Received: from tsltor by mail.uunet.ca with UUCP id <102196(1)>; Fri, 15 Oct 1993 15:19:14 -0400 Received: from osprey.teleride.on.ca by falcon.teleride.on.ca with smtp (Smail3.1.26.7 #5) id m0onufC-0000eOC; Fri, 15 Oct 93 15:18 EDT Received: by vax.teleride.on.ca (MX V3.0A) id 31278; Fri, 15 Oct 1993 15:16:08 EDT Sender: <lou@vax.teleride.on.ca> Date: Fri, 15 Oct 1993 15:16:14 -0400 From: Lou Kates <lou@vax.teleride.on.ca> To: python-list@cwi.nl Message-Id: <009740F6.B05E1F80.31278@vax.teleride.on.ca> Subject: Re: Termcap /curses >| Another approach would be to develop a C to Python translator. >| That would also be a large amount of work and its conceivable >| that certain features would have to be added to Python to make it >| feasible but it would allow one to translate not only the bulk of >| the curses source but many other C libraries all in one go. > >I'm afraid that you would lose the object oriented aspect of Python, which >is the most valuable aspect of Python modules that interact with certain >facets of POSIX. As an example look at the socket module. If the translation >does not allow this kind of abstraction, it would be useless IMHO. > There are numerous libraries that provide OO encapsulations of originally non-OO libraries. Lou Kates, louk@teleride.on.ca Replied: Sat, 16 Oct 1993 18:22:11 +0100 Replied: "Bill Janssen <janssen@parc.xerox.com> " Received: from alpha.Xerox.COM by charon.cwi.nl with SMTP id AA23747 (5.65b/3.11/CWI-Amsterdam); Fri, 15 Oct 1993 21:46:31 +0100 Received: from holmes.parc.xerox.com ([13.1.100.162]) by alpha.xerox.com with SMTP id <11882>; Fri, 15 Oct 1993 13:46:01 PDT Received: by holmes.parc.xerox.com id <16134>; Fri, 15 Oct 1993 13:45:54 -0700 Received: from Messages.7.15.N.CUILIB.3.45.SNAP.NOT.LINKED.holmes.parc.xerox.com.sun4.41 via MS.5.6.holmes.parc.xerox.com.sun4_41; Fri, 15 Oct 1993 13:45:53 -0700 (PDT) Message-Id: <Mgjkk1EB0KGWJDk5kd@holmes.parc.xerox.com> Date: Fri, 15 Oct 1993 13:45:53 PDT Sender: Bill Janssen <janssen@parc.xerox.com> From: Bill Janssen <janssen@parc.xerox.com> To: Guido.van.Rossum@cwi.nl Subject: Re: Python & Sun shared libraries In-Reply-To: <9310150951.AA09117=guido@voorn.cwi.nl> References: <9310150951.AA09117=guido@voorn.cwi.nl> Excerpts from direct: 15-Oct-93 Re: Python & Sun shared lib.. Guido.van.Rossum@cwi.nl (1273) > undefine USE_STDWIN in config.c and you should be all set. The call > to wdone() is not really necessary in the X11 or Mac versions; it *is* > needed for the termcap version to restore the tty settings, but that's > not likely to be very popular at your site... (If it is, you can > always add a function to the module to make an explicit call to > wdone() -- make sure it somehow sabotages wopen() so that after > calling wdone() the program can't continue to open windows and crash > stdwin... Perhaps python should have something like onexit()? Or perhaps each module should have the ability to define `__fini__' on itself, which python will call when it exits? Bill Received: from hermix.markv.com by charon.cwi.nl with SMTP id AA23812 (5.65b/3.11/CWI-Amsterdam); Fri, 15 Oct 1993 21:55:48 +0100 To: tb06@PL122e.EECS.Lehigh.EDU Cc: python-list@cwi.nl In-Reply-To: <9310151901.AA00535@PL122e.EECS.Lehigh.EDU> (message from TERRENCE BRANNON on Fri, 15 Oct 93 15:01:32 -0400) Subject: Re: [request] Impressive Python Software X-Organization: Mark V Systems Ltd. X-Address: 16400 Ventura Blvd Suite 303, Encino, Ca, 91436, USA X-Phone: +1 818 995 7671 (work), +1 818 995 4267 (fax) Date: Fri, 15 Oct 93 13:54:44 PDT From: lance@markv.com Sender: lance@markv.com Message-Id: <9310151354.aa06225@hermix.markv.com> Source-Info: From (or Sender) name not authenticated. I think there are a number of things you left out or mis-stated... I will try to go through them one by one here... > Python does not yet have a robust ftp interface like Emacs' ange-ftp nor > does it have an advanced desk top calculator like Emacs's calc. However > it does have STDWIN, an easy-to-use windowing system. You have not seen ftplib.py then... Very simple to use and fairly complete. Also, the 0.9.9 version not only will work with STDWIN but also comes with full support for X11R4/Motif. > %%% 2. \part {Power} %%% > %%% 2.1.3. \section {Python} %%% > > \section {Python} > \begin{enumerate} > \item > ?? -- Multimedia interface. > \item > ?? -- Remote Procedure Call debugger > \item > texfix -- Crude convert latex to texinfo > \item > throughput -- measure tcp throughput > \item > dutree -- format du(1) output at a tree sorted by size > \item > findlinks -- recursively find links to a given path prefix > \item > lpwatch -- watch BSD line printer queues > \item > suff -- sort a list of files by suffix > \end{enumerate} rsa encryption, www, nntpxmit.py (nntpxmit replacement), and I am sure many more.. I am currently writting a multi-line UNIX BBS that is written in Python. > %%% 2.2. \chapter {Graphics} %%% > \section{Python} > Through the use of the STDWIN paradigm, the same source code > can do graphics in the following systems: > > \begin{enumerate} > \item > X-windows > \item > Macintosh using either Think C 4.02 or MPW C 2.02 > \item > Atari ST > \item > DOS > \item > Silicon Graphics SGI workstations > \end{enumerate} > > This approach allows flexibility but means that no one graphics system's > potential is maximized. the 0.9.9 version also have full X11R4/Motif support... > %%% 2.3. \chapter {User Interface Building} %%% > \section{Python} > Through the use of the STDWIN paradigm, the same source code > can do graphics in the following systems: > > \begin{enumerate} > \item > X-windows > \item > Macintosh using either Think C 4.02 or MPW C 2.02 > \item > Atari ST > \item > DOS > \item > Silicon Graphics SGI workstations > \end{enumerate} > > This approach allows flexibility but means that no one graphics system's > potential is maximized. see section 2.2 > %%% 2.4. \chapter {String Handling} %%% > \section{Python} > It has a string module and regexp module. It has all the string > @emph{search} capabilities of Emacs, but since strings are immutable in > Python, it understandably does not have Emacs Lisp's string replace power. > > \section{Tcl} > Everything in Tcl is a string. It is very easy to map certain > string-intensive applications to Tcl. For example, I wrote a program to > do parallel library database searches in Tcl in about two weeks. Ranking > the 4 languages in terms of how easy it would have been: Tcl, Python, > Emacs, and I cant say about Perl because I gave up on Perl quickly after > buying the book and seeing all those registers and the confusing > context-intensive syntax. did you try to code your program in Python? or as you just assuming that Tcl would have been easier? > %%% 2.5. \chapter {Process Control} %%% > \section{Python} > You would use pipes to do this in Python. This is not 100% true! You also have the full C library of routines.. fork(), waitpid(), wait(), system(), pipes, kill(), etc.. they are all in the os and posix modules... > %%% 2.6. \chapter {Sample Programs} %%% \section{Python} \begin{verbatim} #! /usr/local/bin/python import posix print 'There are ', `len(posix.listdir('.'))`, 'files in this directory' \end{verbatim} > \item > A lengthy file has been entered with records of the form: > \begin{verbatim} > <\n>NAME<\n>ADDRESS<\n>PHONE<\n>---------- > \end{verbatim} > where \begin{verbatim}<\n>\end{verbatim} represents a line feed and the > \begin{verbatim}----------- \end{verbatim} is used to > separate records. Convert all entries in the file to a new format of > the form: > \begin{verbatim}<\n>NAME::ADDRESS::PHONE} > \end{verbatim} \section{Python} \begin{verbatim} #! /usr/local/bin/python import strop fp = open('testFile','r') lines = fp.readlines() # read all lines in and seperate on \n's fp.close() fp = open('testFile','w') for indx in range(0,len(lines)-4,4): fp.write('\n'+lines[indx]+'::'+linex[indx+1]+'::'+lines[indx+2]) fp.close() \end{verbatim} > %%% 4. \part {Ease of Use} %%% > %%% 4.1. \chapter {Documentation/Support} %%% > \section{Python} > Good. Covers everything but how to extend Python through C. Incorrect. Look at python/misc/EXTENDING > \chapter{Program Development} > > \section{Python} > Good. The concept of immutable strings takes some getting used to. The language is VERY regular and very powerful. You have seperate name spaces that allow reuse and an OO design of your applications/scripts. There are HUNDREDS of support modules you can import... > %%% 4.2. \chapter {Extensibility} %%% > > When I say extensibility I mean the ability to add a new keyword or data > type to a language as opposed to adding a new utility. > > \section{Python} > Its possible in C. How to do it in C is not well documented. It is very easy to add new types (I have added about 20 new types of objects to Python both at the C code level as well as in Python code)! -- Lance Ellinghouse lance@markv.com 1231 bit key fingerprint = 56 DA 31 0C 17 51 36 6A 4E D4 E0 11 D9 B8 06 0A 1024 bit key fingerprint = 66 2C 75 F2 E9 1C 32 84 3A E3 B0 5E 48 01 4C 37 You can receive my Public Key by `finger lance@markv.com` Received: from alpha.Xerox.COM by charon.cwi.nl with SMTP id AA25094 (5.65b/3.11/CWI-Amsterdam); Sat, 16 Oct 1993 00:02:29 +0100 Received: from holmes.parc.xerox.com ([13.1.100.162]) by alpha.xerox.com with SMTP id <11965>; Fri, 15 Oct 1993 16:01:52 PDT Received: by holmes.parc.xerox.com id <16134>; Fri, 15 Oct 1993 16:01:48 -0700 Received: from Messages.7.15.N.CUILIB.3.45.SNAP.NOT.LINKED.holmes.parc.xerox.com.sun4.41 via MS.5.6.holmes.parc.xerox.com.sun4_41; Fri, 15 Oct 1993 16:01:42 -0700 (PDT) Message-Id: <IgjmjKEB0KGW5Dk8d0@holmes.parc.xerox.com> Date: Fri, 15 Oct 1993 16:01:42 PDT Sender: Bill Janssen <janssen@parc.xerox.com> From: Bill Janssen <janssen@parc.xerox.com> To: python-list@cwi.nl, Lou Kates <lou@vax.teleride.on.ca> Subject: Re: Termcap /curses In-Reply-To: <009740EC.69AFD6A0.31251@vax.teleride.on.ca> References: <009740EC.69AFD6A0.31251@vax.teleride.on.ca> Excerpts from mail: 15-Oct-93 Re: Termcap /curses Lou Kates@vax.teleride.o (1221) > Another approach would be to develop a C to Python translator. > That would also be a large amount of work and its conceivable > that certain features would have to be added to Python to make it > feasible but it would allow one to translate not only the bulk of > the curses source but many other C libraries all in one go. An interesting idea, but I'm afraid there would be a type mismatch. C is essentially an assembly language; Python is somewhat more abstract and application-oriented. There are many different ways of doing objects, error signalling, etc., in C, and you'd have to keep pointing out what your *particular* object idiom is for it to be *correctly* translated to Python. Similarly for exceptions; you'd have to keep pointing out that in this program, *this* is an exception, while in *that* program, *that* is an exception. How would malloc(), free() be represented? I think you'd wind up with something like the output of a disassembler. It seems to me that the current model of constructing new Python modules in C, like stdwin or dbm, is a reasonable solution to the problem of using external libraries. Bill Received: from alpha.Xerox.COM by charon.cwi.nl with SMTP id AA25598 (5.65b/3.11/CWI-Amsterdam); Sat, 16 Oct 1993 00:54:22 +0100 Received: from holmes.parc.xerox.com ([13.1.100.162]) by alpha.xerox.com with SMTP id <11957>; Fri, 15 Oct 1993 16:53:55 PDT Received: by holmes.parc.xerox.com id <16134>; Fri, 15 Oct 1993 16:53:51 -0700 From: Bill Janssen <janssen@parc.xerox.com> To: tb06@pl122e.eecs.lehigh.edu Subject: Comments on your Survey paper Cc: python-list@cwi.nl Message-Id: <93Oct15.165351pdt.16134@holmes.parc.xerox.com> Date: Fri, 15 Oct 1993 16:53:39 PDT [ Just to admit my biases: I've hacked GNU Emacs on both the C and Elisp level; I've hacked ELK quite a bit, turning it into a real shell, as well as embedding it in some languages; I've dabbled in both Perl and Tcl; but Python is currently my preferred language. It does pretty much everything all these other languages do! When I look at an interpreted extension language, I look for the following (in no particular order): 1) object system 2) byte compiler 3) regular syntax 4) garbage collector 6) floating point support 7) macros 8) regular expression support 9) unix system call support 10) portability (UNIX, Mac, MS-Windows) 11) good file system support 12) reasonable image size 13) threads because I know that sooner or later, I'll need them all. ] OK, comments: Page 6: You say that you're working on extracting the elisp interpreter. I'd say, don't bother. ELK has already done a great job, with the following advantages over elisp: 1) a standard language, with books available, and 2) dynamic loading of new object code. Page 6: Note that all the advantages you ascribe to Perl are also in Python, except that Python tends to do it better! Page 7: There are better FTP sites in the US for Python: gatekeeper.dec.com 16.1.0.2 /pub/plan/python/cwi ftp.uu.net 192.48.96.9 /languages/python wuarchive.wustl.edu 128.252.135.4 /pub Check out lib/python/ftplib.py. Page 14: In addition to STDWIN, Python can manipulate X via Motif, and of course it can do the same kind of things that you mention under the Perl section. I am using it with EZD, Joel Bartlett's very nice WAFE-style system (very nice, check it out!). Page 18: Check out Python's regsub module. It arguably gives you all the string replace power of Emacs. Basically the same as Tcl's, I believe. Page 19: Python's process control is at least as strong as Perl's. In addition, it supports threads (!), so that some of the operations you have to do in another process, using Tcl or Perl, you can do in another thread, in Python. Page 21: List directories: #!/usr/bin/python import posix print len(posix.listdir('.')) None of your hello world examples actually work on the Macintosh, do they? This one (in Python) does (as well as X windows): Hello, World: #!/usr/bin/python import stdwin stdwin.message('Hello, World!') Hello, Bob (I think; I didn't actually try it): #!/usr/bin/python def sub_in_file(file): import regsub import string seen = None fp = open(file, 'r+') lines = fp.readlines() fp.seek(0, 0) for line in lines: if seen: regsub.gsub('Hello Bob', 'Hi James', line) else: seen = (string.find (line, 'Hello Bob') >= 0) fp.write(line) import sys sub_in_file(sys.argv[1]) Page 27: The documents EMBEDDING and EXTENDING (in the src/misc directory, which I agree is misleading) describe both how to add new C primitives to Python, and how to embed it as the extension language for some larger program. Page 28: Note that there is a GNU Emacs mode for Python, as well as a special subprocess mode for it. There are a couple of debuggers shipped with the Python library, one windowing and one command-line-like. Page 30: See my comment on page 27. Note that unlike Perl, new Python modules written in C can be dynamically loaded into a running interpreter. You don't need to relink the image. Adding a new datatype is very easy. Modifying the syntax ("adding a new keyword") doesn't seem very easy. There could be a macro package... Bill Replied: Mon, 18 Oct 1993 10:13:52 +0100 Replied: ""Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> python-list" Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA05113 (5.65b/3.11/CWI-Amsterdam); Sat, 16 Oct 1993 23:37:24 +0100 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa18332; 16 Oct 93 18:37 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA15491; Sat, 16 Oct 1993 18:37:13 -0400 Date: Sat, 16 Oct 1993 18:37:13 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199310162237.AA15491@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: lance@markv.com, tb06@pl122e.eecs.lehigh.edu Subject: fetch - a simple function using python's ftplib Cc: python-list@cwi.nl I hadn't noticed ftplib was even there until it came up on the list. So I hacked out a fetch function. The *intention* was to handle URL's and/or the pathnames in T.Brannon's paper, but I didn't have either at hand when I wrote this, so instead, it takes a pathname of the form: remote.host:/path/filename and by default it will copy (binary) filename into local currect directory. I could have hacked in a strip of the "anonymous@" part, but since the example didn't show the format used if a password was also needed, I didn't bother to do it. Maybe if I dig out a copy of the URL format, I'll do something else with it. But then, maybe that's already in demo/www/wwwlib.py. Well - I wanted to try out the ftplib routines anyway - I need to write a program that backups up PC's thru NCSA Telnet's FTP server to unix tape. That has been on my wish list, but I haven't done anything about it - now that I know ftplib is there, I'll probably give it a try when I have a bit of spare time. The error handling is not as clean and neat as I would probaly want in a final version. This has been minimally tested. ( and not on anything that refuses connections --- I'm relying that the FTP class methods will do the right thing. ) There is a question for Guido (or some other master of python internals) burried in the code: When I moved mt test code into a test function ( so that I could have some cleanup - otherwise when I types 'q' to more, my terminal got zonked! ) and out of the modules global scope, I had to add the "global" declaration - otherwise I got a NameError. I suppose this is a subtle effect of dynamic scoping and the way the function is used as a callback function in another scope. But I would welcome it if someone can explain what's going on in more detail. - Steve Majewski (804-982-0831) <sdm7g@Virginia.EDU> - UVA Department of Molecular Physiology and Biological Physics ------------------------ #!/usr/local/bin/python # # fetch : a simple higher level function to python's ftplib # # given a pathname of format: host.part:/path/filename # 'fetch( pathname )' will fetch pathname into current local directory # 'fetch( pathname, open( FNAME, 'w').write )' will copy remote pathname # into local FNAME, and # 'fetch( pathname, func ) will send blocks pathname to output function func. # ( see test examples at end ) # # other option arg is one of: # 'ascii', 'text', 'mode=ascii', 'mode=text' # which change the transfer mode from binary to text # ( note that retrlines strips tailing newlines ) # # options to be added later: # FTP().login() supports optional args for USER & PASSWD - # add check for optional args "user=" and "pass=" to fetch. # # # shell usage: # fetch.py remotepathnames... # # # - S.D.Majewski/UVA <sdm7g@Virginia.EDU> from ftplib import FTP import string import posixpath def null(): pass FUNC_TYPES = ( type( null ), type( type ) ) # to include both <type 'function'> and <type 'builtin_function_or_method'> TEXT_MODES = ( 'text', 'ascii', 'mode=text', 'mode=ascii' ) def fetch( fname, *opts ): mode = 'bin' # default transfer mode func = None if opts : for arg in opts: if type( arg ) in FUNC_TYPES : func = arg elif arg in TEXT_MODES : mode = 'text' host, dir, file = parse( fname ) if not func : func = open( file, 'w' ).write ftp = FTP().init( host ) ftp.login() ftp.cwd( dir ) print ftp.nlst( file ), 'mode='+mode # this can be removed if mode == 'text' : try: ftp.retrlines( 'RETR ' + file, func ) except IOError: ftp.abort() ftp.quit() raise IOError elif mode == 'bin' : try: ftp.retrbinary( 'RETR '+ file, func, 512 ) except IOError: ftp.abort() ftp.quit() raise IOError ftp.quit() def parse( fname ): list = string.splitfields( fname, ':' ) if len( list ) <> 2 : raise 'NoHostPart' host = list[0] dir, file = posixpath.split( list[1] ) return ( host, dir, file ) # example usage # from posix import popen def test1( ): path = 'uvaarpa.virginia.edu:/pub/hosts' fetch( path ) # "global m" appears to be necessary because mwrite callback # function is called in a different context from the one # in which it is defined. Without it, fetch will raise a # NameError exception. ( The wonders of Dynamic scoping? ) def test2(): global m m = popen( 'more', 'w' ) def mwrite( line ): m.write( line + '\n' ) try: fetch( 'uvaarpa.virginia.edu:/pub/hosts', mwrite, 'text' ) finally: m.close() def test3(): z = popen( 'zcat | more', 'w' ) try: fetch( 'uvaarpa.virginia.edu:/pub/rfc/rfc822.Z', z.write ) finally: z.close() import sys if sys.argv[1:] : for file in sys.argv[1:] : fetch( file ) # ---------- end fetch.py Received: from Sun.COM by charon.cwi.nl with SMTP id AA04591 (5.65b/3.11/CWI-Amsterdam); Mon, 18 Oct 1993 23:06:57 +0100 Received: from Eng.Sun.COM (zigzag.Eng.Sun.COM) by Sun.COM (4.1/SMI-4.1) id AA12025; Mon, 18 Oct 93 15:06:52 PDT Received: from cici.Eng.Sun.COM by Eng.Sun.COM (4.1/SMI-4.1) id AA01203; Mon, 18 Oct 93 15:06:42 PDT Received: from manjushri.Eng.Sun.COM by cici.Eng.Sun.COM (5.0/SMI-SVR4) id AA06739; Mon, 18 Oct 1993 15:06:53 +0800 Date: Mon, 18 Oct 1993 15:06:53 +0800 From: Rafael.Bracho@Eng.Sun.COM (Rafael Bracho) Message-Id: <9310182206.AA06739@cici.Eng.Sun.COM> To: python-list@cwi.nl Subject: Writing classes in C X-Sun-Charset: US-ASCII Content-Length: 228 Hi, I'd like to write a module in C which defines a class, with at least some of its methods executing in C. Is it possible to define classes in C where some (or all) of its methods execute C functions? Thanks, -Rafael Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA20426 (5.65b/3.11/CWI-Amsterdam); Mon, 18 Oct 1993 08:57:10 +0100 Received: by voorn.cwi.nl with SMTP id AA14740 (5.65b/3.8/CWI-Amsterdam); Mon, 18 Oct 1993 08:57:10 +0100 Message-Id: <9310180757.AA14740=guido@voorn.cwi.nl> To: gow@asami.med.ge.com Cc: python-list@cwi.nl Subject: Re: import restrictions In-Reply-To: Your message of "Mon, 18 Oct 1993 16:37:00 MET." <9310180737.AA03216@asami.asami> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Mon, 18 Oct 1993 08:57:09 +0100 Sender: Guido.van.Rossum@cwi.nl > One problem I've been having is that once I have imported > a file of definitions into a python session I can't seem > to get rid of it. When I'm editing a script I'd like > to have python going in another window, edit the script, > re-import it into python, and test it. It seems, however, > that even if I explicitly delete the script's module from > my python session symbol table, the script file is not > re-read/re-interpreted when I import it into the python > session again. This is intentional -- when you import a module, Python remembers that it has imported it so that if you import it again (usually from another module) it won't be parsed, compiled and initialize again. For the situation you are having, however, you can use the reload() built-in function, which forces reparsing etc. of the module. Note that the syntax is reload(expression) where the expression must evaluate to a module object; i.e. you must already have imported the module once. Note that reload() does not recursively reload modules imported by the reloaded module; you will have to do that yourself if it is necessary. --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA21680 (5.65b/3.11/CWI-Amsterdam); Mon, 18 Oct 1993 10:13:53 +0100 Received: by voorn.cwi.nl with SMTP id AA14925 (5.65b/3.8/CWI-Amsterdam); Mon, 18 Oct 1993 10:13:53 +0100 Message-Id: <9310180913.AA14925=guido@voorn.cwi.nl> To: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Cc: python-list@cwi.nl Subject: Re: fetch - a simple function using python's ftplib In-Reply-To: Your message of "Sat, 16 Oct 1993 18:37:13 MET." <199310162237.AA15491@elvis.med.Virginia.EDU> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Mon, 18 Oct 1993 10:13:53 +0100 Sender: Guido.van.Rossum@cwi.nl > I hadn't noticed ftplib was even there until it came up on the list. > So I hacked out a fetch function. The *intention* was to handle > URL's and/or the pathnames in T.Brannon's paper, [...] Thanks! (There is indeed URL parsing support in demo/www/wwwlib.py and/or elsewhere in demo/www.) > There is a question for Guido (or some other master of python internals) > burried in the code: When I moved mt test code into a test function > ( so that I could have some cleanup - otherwise when I types 'q' to > more, my terminal got zonked! ) and out of the modules global scope, > I had to add the "global" declaration - otherwise I got a NameError. > I suppose this is a subtle effect of dynamic scoping and the way the > function is used as a callback function in another scope. But I would > welcome it if someone can explain what's going on in more detail. [referring to:] > # "global m" appears to be necessary because mwrite callback > # function is called in a different context from the one > # in which it is defined. Without it, fetch will raise a > # NameError exception. ( The wonders of Dynamic scoping? ) > > def test2(): > global m > m = popen( 'more', 'w' ) > def mwrite( line ): m.write( line + '\n' ) > try: > fetch( 'uvaarpa.virginia.edu:/pub/hosts', mwrite, 'text' ) > finally: m.close() This is because nested function definitions don't have access to the local variables of the surrounding block -- only to the globals of the containing module. This is done so that lookup of globals doesn't have to walk a chain of dictionaries -- as in C, there are just two nested scopes: locals and globals (and beyond this, built-ins). Therefore, nested functions have only a limited use. This was a deliberate decision, based upon experience with languages allowing arbitraries nesting such as Pascal and both Algols -- code with too many nested scopes is about as readable as code with too many GOTOs. And, of course, in Python, the "proper" way is to use an object-oriented programming style: def test2(): class C: def __init__(self, m ): self.m = m def write( self, line ): self.m.write( line + '\n' ) def close( self ): self.m.close() x = C( popen( 'more', 'w' ) ) try: fetch( 'uvaarpa.virginia.edu:/pub/hosts', x.write, 'text' ) finally: x.close() --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Mon, 18 Oct 1993 08:57:08 +0100 Replied: "gow@asami.med.ge.com python-list" Received: from gemsgw.med.ge.com by charon.cwi.nl with SMTP id AA20202 (5.65b/3.11/CWI-Amsterdam); Mon, 18 Oct 1993 08:36:43 +0100 Received: from gemed.med.ge.com by gemsgw.med.ge.com (4.1/GEMS-1.1) id AA24679; Mon, 18 Oct 93 02:39:59 CDT Received: from anri.yms by gemed.med.ge.com (4.1/SMI-4.1) id AA13094; Mon, 18 Oct 93 02:36:13 CDT Received: from asami.asami by anri.yms (4.1/SMI-4.1) id AA18904; Mon, 18 Oct 93 16:35:39 JST Received: from hakkou.asami by asami.asami (4.1/SMI-4.1) id AA03216; Mon, 18 Oct 93 16:37:00 JST Date: Mon, 18 Oct 93 16:37:00 JST From: gow@asami.med.ge.com Message-Id: <9310180737.AA03216@asami.asami> To: python-list%cwi.nl%gemed@anri.med.ge.com Subject: import restrictions One problem I've been having is that once I have imported a file of definitions into a python session I can't seem to get rid of it. When I'm editing a script I'd like to have python going in another window, edit the script, re-import it into python, and test it. It seems, however, that even if I explicitly delete the script's module from my python session symbol table, the script file is not re-read/re-interpreted when I import it into the python session again. Is there something I'm doing wrong? Is it that I'm in Japan, with it's infamous "import restrictions" :^) ? Or is this the way python (0.98) works? Ed Received: from gateway.sequent.com by charon.cwi.nl with SMTP id AA04752 (5.65b/3.11/CWI-Amsterdam); Mon, 18 Oct 1993 23:27:19 +0100 Received: from [138.95.9.34] by gateway.sequent.com (5.61/1.34) id AA23929; Mon, 18 Oct 93 15:27:50 -0700 Received: from ushqgw1.sequent.com by relay1.sequent.com (5.65/crg/11) id AA17963; Mon, 18 Oct 93 15:34:17 -0700 Received: by ushqgw.sequent.com with Microsoft Mail id <2CC317A7@ushqgw.sequent.com>; Mon, 18 Oct 93 15:24:39 PDT From: "Jaap Vermeulen (jaap)" <jaap@sequent.com> To: python-list <python-list@cwi.nl>, "Rafael.Bracho" <Rafael.Bracho@Eng.Sun.COM> Subject: RE: Writing classes in C Date: Mon, 18 Oct 93 15:23:00 PDT Message-Id: <2CC317A7@ushqgw.sequent.com> Encoding: 11 TEXT X-Mailer: Microsoft Mail V3.0 | I'd like to write a module in C which defines a class, with at least | some of its methods executing in C. Is it possible to define classes | in C where some (or all) of its methods execute C functions? Just make it a built-in object, such as fileobject. If you need to access it using a user-defined class, just write a class wrapper around the built-in object. -Jaap- Replied: Thu, 21 Oct 1993 10:18:33 +0100 Replied: "Bill Janssen <janssen@parc.xerox.com> python-list" Received: from alpha.Xerox.COM by charon.cwi.nl with SMTP id AA22159 (5.65b/3.11/CWI-Amsterdam); Thu, 21 Oct 1993 07:28:17 +0100 Received: from holmes.parc.xerox.com ([13.1.100.162]) by alpha.xerox.com with SMTP id <12265>; Wed, 20 Oct 1993 23:28:06 PDT Received: by holmes.parc.xerox.com id <16134>; Wed, 20 Oct 1993 23:28:02 -0700 From: Bill Janssen <janssen@parc.xerox.com> To: python-list@cwi.nl Subject: obtaining the reversal of a sequence? Message-Id: <93Oct20.232802pdt.16134@holmes.parc.xerox.com> Date: Wed, 20 Oct 1993 23:27:57 PDT I've encountered the problem where I'd like to have a sequence that is traversed in both directions equally frequently. It's a display list, and is traversed from back to front, to paint the window, and from front to back, to find the innermost element enclosing a point. Clearly, the ``for foo in x'' construct works well for one of the two cases, but what's the efficient way to traverse the list in reverse order? The best I can come up with is: tmp = list[:] tmp.reverse() for x in tmp: blah... and that's so inefficient I believe there must be some trick tucked away to make this easier. Bill Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA24624 (5.65b/3.11/CWI-Amsterdam); Thu, 21 Oct 1993 10:18:33 +0100 Received: by voorn.cwi.nl with SMTP id AA24516 (5.65b/3.8/CWI-Amsterdam); Thu, 21 Oct 1993 10:18:33 +0100 Message-Id: <9310210918.AA24516=guido@voorn.cwi.nl> To: Bill Janssen <janssen@parc.xerox.com> Cc: python-list@cwi.nl Subject: Re: obtaining the reversal of a sequence? In-Reply-To: Your message of "Wed, 20 Oct 1993 23:27:57 MDT." <93Oct20.232802pdt.16134@holmes.parc.xerox.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Thu, 21 Oct 1993 10:18:33 +0100 Sender: Guido.van.Rossum@cwi.nl > I've encountered the problem where I'd like to have a sequence that is > traversed in both directions equally frequently. It's a display list, and > is traversed from back to front, to paint the window, and from front to > back, to find the innermost element enclosing a point. > > Clearly, the ``for foo in x'' construct works well for one of the two > cases, but what's the efficient way to traverse the list in reverse order? > The best I can come up with is: > > tmp = list[:] > tmp.reverse() > for x in tmp: > blah... > > and that's so inefficient I believe there must be some trick tucked away > to make this easier. Hmm, I don't think there's a trick for this in the language. You could reverse the list in place and reverse it back after the loop -- reverse() is actually pretty fast compared to doing anything in Python, and it's certainly faster than the code given here: the list[:] operation will take more time than an extra reverse() call because (a) it allocates two new blocks of memory, (b) it has to increment the reference counts of all list items, and (c) it has to undo all that when you're done. Alternatively, if you can't afford to reverse the list in place because other users of it may get confused, you can construct the reverse index sequence manually: i = len(list) while i > 0: i = i-1 x = list[i] blah... Using range() will create a list containing lots of new integer objects and thus be the slowest of all, unless the list changes infrequently and you can save a permanent copy of it -- but that's a maintenance nightmare. --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA13519 (5.65b/3.11/CWI-Amsterdam); Fri, 22 Oct 1993 09:02:29 +0100 Received: by voorn.cwi.nl with SMTP id AA27058 (5.65b/3.8/CWI-Amsterdam); Fri, 22 Oct 1993 09:02:29 +0100 Message-Id: <9310220802.AA27058=guido@voorn.cwi.nl> To: Bill Janssen <janssen@parc.xerox.com> Cc: python-list@cwi.nl Subject: Re: obtaining the reversal of a sequence? In-Reply-To: Your message of "Thu, 21 Oct 1993 12:11:13 MDT." <kglhvFgB0KGWI2rS9G@holmes.parc.xerox.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Fri, 22 Oct 1993 09:02:28 +0100 Sender: Guido.van.Rossum@cwi.nl Bill Janssen writes: > It occurs to me that the compiler could probably generate optimized code > in the case where it sees the statement > > for <ident> in range(<expression>): > > The list result of range() never really needs to exist, in this case, no? Well the compiler isn't very good at recognizing calls to built-in functions ('range' could be a local identifier with a different meaning). But someone else proposed that range() return a new object type that behaves like a sequence but doesn't store all its elements, just returns the one you ask for. I am beginning to like this solution. It would not be 100 percent compatible, since uses of range() in other contexts would work differently or not at all (e.g. you can't initialize a list with a range and then remove items from it) but those uses would be a far minority. An alternative solution, used in ABC, would be to have an efficient alternative representation of list objects consisting of ranges. Unfortunately this would complicate the implementation of all list operations, so I'm not in favor of it, even though it would be marginally cleaner for the user. Any other opinions? --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> To: Bill Janssen <janssen@parc.xerox.com> cc: python-list Subject: Re: obtaining the reversal of a sequence? In-reply-to: Your message of "Thu, 21 Oct 1993 12:11:13 MDT." <kglhvFgB0KGWI2rS9G@holmes.parc.xerox.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Fri, 22 Oct 1993 09:02:28 +0100 Sender: guido Bill Janssen writes: > It occurs to me that the compiler could probably generate optimized code > in the case where it sees the statement > > for <ident> in range(<expression>): > > The list result of range() never really needs to exist, in this case, no? Well the compiler isn't very good at recognizing calls to built-in functions ('range' could be a local identifier with a different meaning). But someone else proposed that range() return a new object type that behaves like a sequence but doesn't store all its elements, just returns the one you ask for. I am beginning to like this solution. It would not be 100 percent compatible, since uses of range() in other contexts would work differently or not at all (e.g. you can't initialize a list with a range and then remove items from it) but those uses would be a far minority. An alternative solution, used in ABC, would be to have an efficient alternative representation of list objects consisting of ranges. Unfortunately this would complicate the implementation of all list operations, so I'm not in favor of it, even though it would be marginally cleaner for the user. Any other opinions? --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from uunet.ca by charon.cwi.nl with SMTP id AA15402 (5.65b/3.11/CWI-Amsterdam); Fri, 22 Oct 1993 11:13:35 +0100 Received: from tsltor by mail.uunet.ca with UUCP id <100970(5)>; Fri, 22 Oct 1993 06:13:18 -0400 Received: from osprey.teleride.on.ca by falcon.teleride.on.ca with smtp (Smail3.1.26.7 #5) id m0oqIZG-0000eOC; Fri, 22 Oct 93 05:13 EDT Received: by vax.teleride.on.ca (MX V3.0A) id 32455; Fri, 22 Oct 1993 05:11:48 EDT Sender: <lou@vax.teleride.on.ca> Date: Fri, 22 Oct 1993 05:12:14 -0400 From: Lou Kates <lou@vax.teleride.on.ca> To: Guido.van.Rossum@cwi.nl Cc: python-list@cwi.nl Message-Id: <00974622.789D0DA0.32455@vax.teleride.on.ca> Subject: Re: obtaining the reversal of a sequence? >> It occurs to me that the compiler could probably generate optimized code >> in the case where it sees the statement >> >> for <ident> in range(<expression>): >> >> The list result of range() never really needs to exist, in this case, no? > >Well the compiler isn't very good at recognizing calls to built-in >functions ('range' could be a local identifier with a different >meaning). But someone else proposed that range() return a new object >type that behaves like a sequence but doesn't store all its elements, >just returns the one you ask for. > Presumably this is not the only instance where lazy evaluation could apply to Python. Also, the Icon language is something to look at here since its generation and lazy evaluation of infinite sequences is close to what is being discussed here. Lou Kates, louk@teleride.on.ca Received: from anjer.cwi.nl by charon.cwi.nl with SMTP id AA14555 (5.65b/3.11/CWI-Amsterdam); Fri, 22 Oct 1993 10:19:39 +0100 Received: by anjer.cwi.nl with SMTP id AA01355 (5.65b/3.8/CWI-Amsterdam); Fri, 22 Oct 1993 10:19:39 +0100 Message-Id: <9310220919.AA01355=soede@anjer.cwi.nl> To: Guido.van.Rossum@cwi.nl Cc: python-list@cwi.nl Subject: Re: obtaining the reversal of a sequence? In-Reply-To: Your message of "Fri, 22 Oct 1993 09:02:28 MET." <9310220802.AA27058=guido@voorn.cwi.nl> Date: Fri, 22 Oct 1993 10:19:38 +0100 From: Dirk Soede <Dirk.Soede@cwi.nl> >meaning). But someone else proposed that range() return a new object >type that behaves like a sequence but doesn't store all its elements, >just returns the one you ask for. This is the same as in Smalltalk. There a loop is actually a method of a Sequence which executes the code of the loop on each Sequence element. The Sequence is only accessed through `first' and `next'. So it can also choose to generate the next item only when requested. This sounds very clean to me. You could also have a reverse loop when Sequences would have methods last and previous. >I am beginning to like this solution. It would not be 100 percent >compatible, since uses of range() in other contexts would work >differently or not at all (e.g. you can't initialize a list with a >range and then remove items from it) but those uses would be a far Maybe when a range object is copied it should have a copy method, which returns a real list with all elements. Dirk Soede Centre for Mathematics & Computer Science (CWI), Kruislaan 413, 1098 SJ Amsterdam, The Netherlands. Email:soede@cwi.nl, Tel: +31-20-592 4009 Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA00526 (5.65b/3.11/CWI-Amsterdam); Fri, 22 Oct 1993 23:02:41 +0100 Received: from galen.med.virginia.edu by uvaarpa.virginia.edu id aa19812; 22 Oct 93 18:02 EDT Received: by galen.med.Virginia.EDU (5.67a8/1.34) id AA46522; Fri, 22 Oct 1993 18:02:34 -0400 Date: Fri, 22 Oct 1993 18:02:34 -0400 From: "Steven D. Majewski" <sdm7g@galen.med.virginia.edu> Message-Id: <199310222202.AA46522@galen.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: python-list@cwi.nl Subject: the proper name for dictionaries,maps,associative-arrays,tables... There has been some discussion in comp.language.perl on the best or proper name for dictionaries/associative-arrays/maps/ tables/hash-tables/etc. On Oct 19, 8:46, Larry Wall wrote: > > In article <CF3Mwz.Hxr@bcstec.ca.boeing.com> ced@bcstec.ca.boeing.com (Charles Derykus) writes: > : I think assoc.arrays deserve something whimsical. Maybe, along > : the line of > : > : joytable > : happyhash > : funarray (say it fast) > : ? > : > : After all, Perl is getting awfully serious :-) > > I think that's the reason I lean towards "hash". "map" is so...sober... > > Just try to say "hash" with a straight face. > > Larry > > > -- End of excerpt from lwall@netlabs.com (Larry Wall) For obvious reasons, I think the python documentation should be changed to call these objects "SPAM" ! - Steve Majewski [ P.S. Elvis was dead. But he is alive again. If anyone has had bouncing mail to me, would you please resend it to sdm7g@Virginia.EDU. The domain addressing is better - it can be redirected more easily. ] Replied: Mon, 25 Oct 1993 11:46:34 +0100 Replied: "Tim Peters <tim@ksr.com> " Received: from hopscotch.ksr.com by charon.cwi.nl with SMTP id AA00702 (5.65b/3.11/CWI-Amsterdam); Fri, 22 Oct 1993 23:23:09 +0100 Received: from ksr.com (frankenstein.ksr.com) by hopscotch.ksr.com with SMTP id AA12244; Fri, 22 Oct 1993 18:22:47 -0400 Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA08354; Fri, 22 Oct 93 18:23:43 EDT Received: by kaos.ksr.com (4.1/KSR-2.0) id AA22366; Fri, 22 Oct 93 18:23:40 EDT Message-Id: <9310222223.AA22366@kaos.ksr.com> To: python-list@cwi.nl Subject: Non-list ranges (was Re: obtaining the reversal of a sequence?) Date: Fri, 22 Oct 93 18:23:39 -0400 From: Tim Peters <tim@ksr.com> > > for <ident> in range(<expression>): > > Well the compiler isn't very good at recognizing calls to built-in > functions ('range' could be a local identifier with a different > meaning). Instead of the compiler, could the _runtime_ be made smart enough to recognize that 'range' is being invoked in a context where a list isn't truly needed? Seems to me this use in 'for' is the only one worth special-casing (I've never seen, e.g., someone write 'if i in range(n)', or other non-for contexts where a list isn't needed). > But someone else proposed that range() return a new object type that > behaves like a sequence but doesn't store all its elements, just > returns the one you ask for. ... If this is the way to do it, I'd rather that range be left alone & a new builtin introduced. Think of all the Sieve of Eratosthenes programs you'll break otherwise <wink>. Or perhaps range could return an object of this new non-storing type, and that also magically transforms itself into a vanilla list if used in a context that requires a genuine list (including, but not limited to, the "copy" context mentioned by Dirk). In fact, I like this one best of all -- users wouldn't need to know the non-storing type existed. It's an implementation hack, as it should be <grin>. > An alternative solution, used in ABC, would be to have an efficient > alternative representation of list objects consisting of ranges. Agreed that's overkill; not common enough in Python (outside of "for") to justify slowing down all lists. voting-for-a-dirty-hack-under-the-covers-ly y'rs - tim Tim Peters tim@ksr.com not speaking for Kendall Square Research Corp Replied: Mon, 25 Oct 1993 10:25:03 +0100 Replied: "Bill Janssen <janssen@parc.xerox.com> python-list@cwi.nl" Received: from alpha.Xerox.COM by charon.cwi.nl with SMTP id AA01825 (5.65b/3.11/CWI-Amsterdam); Sat, 23 Oct 1993 00:39:37 +0100 Received: from holmes.parc.xerox.com ([13.1.100.162]) by alpha.xerox.com with SMTP id <11936>; Fri, 22 Oct 1993 16:39:14 PDT Received: by holmes.parc.xerox.com id <16134>; Fri, 22 Oct 1993 16:39:08 -0700 Received: from Messages.7.15.N.CUILIB.3.45.SNAP.NOT.LINKED.holmes.parc.xerox.com.sun4.41 via MS.5.6.holmes.parc.xerox.com.sun4_41; Fri, 22 Oct 1993 16:39:04 -0700 (PDT) Message-Id: <ogm6wM4B0KGW82rNZq@holmes.parc.xerox.com> Date: Fri, 22 Oct 1993 16:39:04 PDT Sender: Bill Janssen <janssen@parc.xerox.com> From: Bill Janssen <janssen@parc.xerox.com> To: python-list@cwi.nl Subject: file.writelines()? To write scripts, it would be handy to have something that lets one cat a file to a file, something that's the equivalent of readlines(), but on the output side (writelines()?), so that you could write out.writelines(in.readlines()) Bill Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA28365 (5.65b/3.11/CWI-Amsterdam); Mon, 25 Oct 1993 10:25:05 +0100 Received: by voorn.cwi.nl with SMTP id AA03888 (5.65b/3.8/CWI-Amsterdam); Mon, 25 Oct 1993 10:25:04 +0100 Message-Id: <9310250925.AA03888=guido@voorn.cwi.nl> To: Bill Janssen <janssen@parc.xerox.com> Cc: python-list@cwi.nl Subject: Re: file.writelines()? In-Reply-To: Your message of "Fri, 22 Oct 1993 16:39:04 MDT." <ogm6wM4B0KGW82rNZq@holmes.parc.xerox.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Mon, 25 Oct 1993 10:25:03 +0100 Sender: Guido.van.Rossum@cwi.nl > To write scripts, it would be handy to have something that lets one cat > a file to a file, something that's the equivalent of readlines(), but on > the output side (writelines()?), so that you could write > > out.writelines(in.readlines()) I just encountered the same need. Consider it added to the next release. (Want a patch? Mail me.) --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> To: Bill Janssen <janssen@parc.xerox.com> cc: python-list@cwi.nl Subject: Re: file.writelines()? In-reply-to: Your message of "Fri, 22 Oct 1993 16:39:04 MDT." <ogm6wM4B0KGW82rNZq@holmes.parc.xerox.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Mon, 25 Oct 1993 10:25:03 +0100 Sender: guido > To write scripts, it would be handy to have something that lets one cat > a file to a file, something that's the equivalent of readlines(), but on > the output side (writelines()?), so that you could write > > out.writelines(in.readlines()) I just encountered the same need. Consider it added to the next release. (Want a patch? Mail me.) --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Mon, 25 Oct 1993 11:38:47 +0100 Replied: "gum@hal.com (John Gmuender) sijben@pegasus.esprit.ec.org" Received: from HAL.COM by charon.cwi.nl with SMTP id AA29548 (5.65b/3.11/CWI-Amsterdam); Mon, 25 Oct 1993 11:32:09 +0100 Received: from gumworks.hal.com by hal.com (4.1/SMI-4.1.1) id AA11142; Mon, 25 Oct 93 03:32:05 PDT Received: by gumworks.hal.com (4.1/SMI-4.1.2) id AA19142; Mon, 25 Oct 93 03:30:32 PDT From: gum@hal.com (John Gmuender) Message-Id: <9310251030.AA19142@gumworks.hal.com> Subject: compiling stdwin port x11 on X11R5 ... and XLIB_ILLEGAL_ACCESS define ... To: python-list@cwi.nl Date: Mon, 25 Oct 93 3:30:31 PDT Cc: massing@hal.com (Mike Massing) X-Mailer: ELM [version 2.3 PL11] Hi there: I was just trying to add stdwin module to python and ran into this snag when compiling stdwin ... % make cc -c -I/tmp_mnt/sim/gumtools/src/python/stdwin/H -g /tmp_mnt/sim/gumtools/src/python/stdwin/Ports/x11/font.c "/tmp_mnt/sim/gumtools/src/python/stdwin/Ports/x11/font.c", line 117: gid undefined which comes from this code snippet .... ... if (stdfont.name == NULL) { stdfont.info= XQueryFont(_wd, DefaultGCOfScreen(_ws)->gid); if (stdfont.info == NULL) _wfatal("_winitfonts: no server default font"); stdfont.info->fid= 0; } ... So, I started looking through everything and figured out that X11R5 Xlib.h (as opposed to X11R4 Xlib.h), requires the define XLIB_ILLEGAL_ACCESS in order to reach into the GC and grab the gid. I happily added this to the CFLAGS of the Makefile ... CFLAGS= $(CPPFLAGS) $(OPTS) -DXLIB_ILLEGAL_ACCESS and wholla ... it compiles! Of course, this has probably been figured out fifty times before ... I thought I would relate it anyway. Now, on to adding stdwin to python :) --__ ____ /_//_// / / __/ gum@hal.com To: gum@hal.com (John Gmuender) cc: sijben@pegasus.esprit.ec.org cc: python-list@cwi.nl, massing@hal.com (Mike Massing) Subject: Re: compiling stdwin port x11 on X11R5 ... and XLIB_ILLEGAL_ACCESS define ... In-reply-to: Your message of "Mon, 25 Oct 1993 03:30:31 MDT." <9310251030.AA19142@gumworks.hal.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Mon, 25 Oct 1993 11:38:47 +0100 Sender: guido > So, I started looking through everything and figured out that > X11R5 Xlib.h (as opposed to X11R4 Xlib.h), requires the define > > XLIB_ILLEGAL_ACCESS > > in order to reach into the GC and grab the gid. Thanks for the bug report and the fix. I've heard of the bug once before for a DEC alpha running OSF/1. It appears not to be a problem with the R5 Xlib.h straight from MIT that *I* am using. Maybe it is an OSF/1 problem? Anyway, I imagine that eventually sdtwin should be fixed to use the proper way of getting access to these variables (otherwise the define wouldn't have that name would it?). Paul Sijben, do you still have the fixes you applied to stdwin for this? --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA01155 (5.65b/3.11/CWI-Amsterdam); Mon, 25 Oct 1993 12:35:59 +0100 Received: by voorn.cwi.nl with SMTP id AA04771 (5.65b/3.8/CWI-Amsterdam); Mon, 25 Oct 1993 12:35:59 +0100 Message-Id: <9310251135.AA04771=guido@voorn.cwi.nl> Subject: Re: Non-list ranges (was Re: obtaining the reversal of a sequence?) To: python-list@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Mon, 25 Oct 1993 12:35:58 +0100 From: Guido van Rossum <Guido.van.Rossum@cwi.nl> Tim Peters writes: > Instead of the compiler, could the _runtime_ be made smart enough to > recognize that 'range' is being invoked in a context where a list isn't > truly needed? Seems to me this use in 'for' is the only one worth > special-casing (I've never seen, e.g., someone write 'if i in range(n)', > or other non-for contexts where a list isn't needed). Hmm, I suppose the compiler could recognize the range() call and generate an instruction to set a hint flag that would be picked up by the built-in range(). Will think about it some more... > If this is the way to do it, I'd rather that range be left alone & a new > builtin introduced. Think of all the Sieve of Eratosthenes programs > you'll break otherwise <wink>. Really? Actually the only non-for-loop use of range() I can imagine is your "enumerated values" trick: [red, green, blue] = range(3) > Or perhaps range could return an object of this new non-storing type, and > that also magically transforms itself into a vanilla list if used in a > context that requires a genuine list (including, but not limited to, the > "copy" context mentioned by Dirk). In fact, I like this one best of all > -- users wouldn't need to know the non-storing type existed. It's > an implementation hack, as it should be <grin>. Jack proposed this too. It appears possible: when a true-list-specific operation is called for, just update the structure's contents and patch the type pointer, assuming a range object takes no more space than a list object. However we rejected it because it would lead to a very obscure class of errors: there is code around which compares an object's type with type([]) and this would fail very mysteriously on range objects: for all practical purposes they behave as lists, but not when their type is taken... --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> PS Tim: you got an earlier draft of this letter which accidentally attributed the enum trick to Steve -- sorry about that! The list archives unambiguously show that you proposed it first :-) Replied: Tue, 26 Oct 1993 10:45:38 +0100 Replied: "Bill Janssen <janssen@parc.xerox.com> python-list" Received: from alpha.Xerox.COM by charon.cwi.nl with SMTP id AA12218 (5.65b/3.11/CWI-Amsterdam); Tue, 26 Oct 1993 01:35:53 +0100 Received: from holmes.parc.xerox.com ([13.1.100.162]) by alpha.xerox.com with SMTP id <11717>; Mon, 25 Oct 1993 17:35:34 PDT Received: by holmes.parc.xerox.com id <16134>; Mon, 25 Oct 1993 17:35:23 -0700 From: Bill Janssen <janssen@parc.xerox.com> To: python-list@cwi.nl Subject: strange thing about boolean expressions? Message-Id: <93Oct25.173523pdt.16134@holmes.parc.xerox.com> Date: Mon, 25 Oct 1993 17:35:16 PDT Why can't I use the following? v = None x = v or 'foo' I get a syntax error. Aren't boolean expressions valid on the right hand side of an assignment? I'd imagine that this evals to 'foo'. Bill Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA12296 (5.65b/3.11/CWI-Amsterdam); Tue, 26 Oct 1993 01:45:17 +0100 Received: from galen.med.virginia.edu by uvaarpa.virginia.edu id aa03858; 25 Oct 93 20:45 EDT Received: by galen.med.Virginia.EDU (5.67a8/1.34) id AA41898; Mon, 25 Oct 1993 20:44:41 -0400 Date: Mon, 25 Oct 1993 20:44:41 -0400 From: "Steven D. Majewski" <sdm7g@galen.med.virginia.edu> Message-Id: <199310260044.AA41898@galen.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: Bill Janssen <janssen@parc.xerox.com> Subject: Re: strange thing about boolean expressions? Cc: python-list@cwi.nl On Oct 25, 17:35, Bill Janssen wrote: > > Why can't I use the following? > > v = None > x = v or 'foo' > > I get a syntax error. Aren't boolean expressions valid on the > right hand side of an assignment? I'd imagine that this evals > to 'foo'. > x = ( v or 'foo' ) will work as expected. The parends are necessary. I think this is a relic in the parser of the early days when boolean equal was "=" rather than "==" . [ This came up in discussion earlier, but elvis.med.virginia.edu is again DEAD, and I can't get access to my python-list archive. ] - Steve Majewski Replied: Tue, 26 Oct 1993 14:47:52 +0100 Replied: "python-list@cwi.nl " Replied: Tue, 26 Oct 1993 10:59:34 +0100 Replied: "Tim Peters <tim@ksr.com> python-list" Received: from hopscotch.ksr.com by charon.cwi.nl with SMTP id AA13784 (5.65b/3.11/CWI-Amsterdam); Tue, 26 Oct 1993 05:16:25 +0100 Received: from ksr.com (frankenstein.ksr.com) by hopscotch.ksr.com with SMTP id AA26880; Tue, 26 Oct 1993 00:16:20 -0400 Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA07307; Tue, 26 Oct 93 00:16:16 EDT Received: by kaos.ksr.com (4.1/KSR-2.0) id AA19635; Tue, 26 Oct 93 00:15:37 EDT Message-Id: <9310260415.AA19635@kaos.ksr.com> To: Guido.van.Rossum@cwi.nl Subject: Re: Non-list ranges Cc: python-list@cwi.nl Date: Tue, 26 Oct 93 00:15:36 -0400 From: Tim Peters <tim@ksr.com> > > [tim, whining that 'range' should be special-cased in 'for', by any > > dirty trick that works] > > [how about at runtime via a context-sensitive trick?] > [guido] > Hmm, I suppose the compiler could recognize the range() call and > generate an instruction to set a hint flag that would be picked up by > the built-in range(). Will think about it some more... If that's doable, I like it! I don't understand the implementation well enough to be helpful. As a user, I whine that range makes perfect sense the way it is already, and just needs to be trickier "somehow" in the one context where its existing semantics are correct but overbearingly inefficient. > > If this is the way to do it, I'd rather that range be left alone & a new > > builtin introduced. Think of all the Sieve of Eratosthenes programs > > you'll break otherwise <wink>. > > Really? Actually the only non-for-loop use of range() I can imagine > is your "enumerated values" trick: > > [red, green, blue] = range(3) Drat -- I was so relieved when you first attributed this kludgexxxxxx fine technique to Majewski <wink>. Here's a prime sieve program I pass around here for pedagogical purposes; note that it uses "range" in 3 distinct ways, only one of which is clearly optimizable: def siv( n ): # return list of primes, in order, <= n if n <= 3: return range(2,n+1) if n & 1: n = n + 1 primes = range(3,n,2) primes.insert(0,2) i = 1 p = primes[i] sq = p*p while sq <= n: for x in range( sq, n, 2*p ): if x in primes: primes.remove(x) i = i + 1 p = primes[i] sq = p * p return primes Of course there are quicker ways to write the venerable sieve in Python, but this way is clean and people have found it instructive. God only knows how many have adopoted similar uses for range. range-used-to-return-an-arithmetic-sequence-as-a-list is also useful for the same reasons APL's iota function, and the Emac's calculator Calc's function calc-index (both of which do much the same thing), are useful. That's in support of a style of interactive computation that's not built in to Python, but very easy to do in Python given a handful of helper functions (like the 'map' and 'func' examples from a different thread). You can also find non-'for' examples of 'range' in the library you distribute <wink>: auds.py: list = range(RATE) calendar.py: r7 = range(7) dis.py:opname = range(256) Certainly the 'for' use is overwhelmingly most common, though. > > Or perhaps range could return an object of this new non-storing type, and > > that also magically transforms itself into a vanilla list if used in a > > context that requires a genuine list ... > [type() creates a problem] I agree that's a problem, and will refrain from suggesting a kludge in the type system too to worm around it. My view is that range semantics are fine as-is, and speeding things up in the 'for' context is simply a matter of translator optimization (& being in the optimization biz myself, there is no limit to the sickness I'll introduce behind the scenes to make a pleasant abstraction appear healthy). If you'd rather make range magical in a new & incompatible way, I can live with that too. Question: In the absence of a from something import * statement, are there other cases where Python cannot (in principle, & at compile time) tell whether the name 'range' denotes the built-in? This is the tip of a much broader question, relevant a few years down the road, when Python has taken over much of the world & I'll be thinking of making a living by selling an optimizing Python compiler <smile>. cleanliness-is-next-to-sterility-ly y'rs - tim Tim Peters tim@ksr.com not speaking for Kendall Square Research Corp Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA17943 (5.65b/3.11/CWI-Amsterdam); Tue, 26 Oct 1993 10:45:38 +0100 Received: by voorn.cwi.nl with SMTP id AA07746 (5.65b/3.8/CWI-Amsterdam); Tue, 26 Oct 1993 10:45:38 +0100 Message-Id: <9310260945.AA07746=guido@voorn.cwi.nl> To: Bill Janssen <janssen@parc.xerox.com> Cc: python-list@cwi.nl Subject: Re: strange thing about boolean expressions? In-Reply-To: Your message of "Mon, 25 Oct 1993 17:35:16 MDT." <93Oct25.173523pdt.16134@holmes.parc.xerox.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Tue, 26 Oct 1993 10:45:38 +0100 Sender: Guido.van.Rossum@cwi.nl > Why can't I use the following? > > v = None > x = v or 'foo' > > I get a syntax error. Aren't boolean expressions valid on the > right hand side of an assignment? I'd imagine that this evals > to 'foo'. Consider it fixed in 1.0. It is a relic from the days when '=' was also the equality comparison operator. It also catches typos like x == 0 # intended: x = 0 which can be relly annoying to find, but I don't think the advantage of catching those is worth the lack of orthogonality and surprise at not being able to write "x = v or 'foo'". --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA18185 (5.65b/3.11/CWI-Amsterdam); Tue, 26 Oct 1993 10:59:36 +0100 Received: by voorn.cwi.nl with SMTP id AA07835 (5.65b/3.8/CWI-Amsterdam); Tue, 26 Oct 1993 10:59:36 +0100 Message-Id: <9310260959.AA07835=guido@voorn.cwi.nl> To: Tim Peters <tim@ksr.com> Cc: python-list@cwi.nl Subject: Optimizing Python In-Reply-To: Your message of "Tue, 26 Oct 1993 00:15:36 MET." <9310260415.AA19635@kaos.ksr.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Tue, 26 Oct 1993 10:59:35 +0100 Sender: Guido.van.Rossum@cwi.nl Tim Peters brings up another interesting > Question: In the absence of a > from something import * > > statement, are there other cases where Python cannot (in principle, & at > compile time) tell whether the name 'range' denotes the built-in? This > is the tip of a much broader question, relevant a few years down the > road, when Python has taken over much of the world & I'll be thinking of > making a living by selling an optimizing Python compiler <smile>. Actually, since built-in names come after module-global names, it is always possible to sabotage a module by doing something like def sick_range(n): return range(1, n+1) import foobar foobar.range = sick_range print foobar.innocent_function() Depending upon the use that foobar.innocent_function() makes of range() this could have no effect, a benign effect, a humorous effect, or a disastrous effect... A global scan of all modules might prove that there is no redefinition of 'range' anywhere, but a single use of exec or even setattr may make everything uncertain again... --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA24064 (5.65b/3.11/CWI-Amsterdam); Tue, 26 Oct 1993 14:47:53 +0100 Received: by voorn.cwi.nl with SMTP id AA09118 (5.65b/3.8/CWI-Amsterdam); Tue, 26 Oct 1993 14:47:53 +0100 Message-Id: <9310261347.AA09118=guido@voorn.cwi.nl> To: python-list@cwi.nl Subject: Non-list ranges -- is it worth it? From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Tue, 26 Oct 1993 14:47:52 +0100 Sender: Guido.van.Rossum@cwi.nl I just did a reality check. Someone from XVT donated a range object implementation (thanks!) and I put it in under a different name ("xrange"). Results: a for loop with an empty body ("pass") over range(100000), which actually creates a list and 100,000 integer objects, takes about 3.13 seconds on my machine (fastest of 3 runs) while the same loop using xrange(100000) takes 3.07 (best of 3 in both cases). That is a speed-up of less than 2 percent! This was on an SGI Indigo with a 50 MHZ MIPS R4000 CPU. On a Sun ELC, the results are even weirder: the loop using xrange() takes 17.5 secs, while using range() it takes only 12.8 seconds!!! A possible explanation for this unexpectged behavior might be instruction cache size on the Sparc chip: creating 100,000 integer objects in a tight loop (as range() does) may execute entirely out of the cache and thus be much faster than creating one object on each iteration through the for loop, where many other lines of C code are hit in between... Note that even though this creates 100,000 integer objects, it does not make 100,000 calls to malloc() -- the allocation of integers is already optimized (to save 25% on space). The measurements were actually done using a version of the interpreter with some other optimizations (such as keeping a cache of small integers) but this shouldn't affect the measurements much. My personal conclusion: it's not worth optimizing range() at all... --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> "Meten is weten" To: python-list@cwi.nl Subject: Non-list ranges -- is it worth it? From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Tue, 26 Oct 1993 14:47:52 +0100 Sender: guido I just did a reality check. Someone from XVT donated a range object implementation (thanks!) and I put it in under a different name ("xrange"). Results: a for loop with an empty body ("pass") over range(100000), which actually creates a list and 100,000 integer objects, takes about 3.13 seconds on my machine (fastest of 3 runs) while the same loop using xrange(100000) takes 3.07 (best of 3 in both cases). That is a speed-up of less than 2 percent! This was on an SGI Indigo with a 50 MHZ MIPS R4000 CPU. On a Sun ELC, the results are even weirder: the loop using xrange() takes 17.5 secs, while using range() it takes only 12.8 seconds!!! A possible explanation for this unexpectged behavior might be instruction cache size on the Sparc chip: creating 100,000 integer objects in a tight loop (as range() does) may execute entirely out of the cache and thus be much faster than creating one object on each iteration through the for loop, where many other lines of C code are hit in between... Note that even though this creates 100,000 integer objects, it does not make 100,000 calls to malloc() -- the allocation of integers is already optimized (to save 25% on space). The measurements were actually done using a version of the interpreter with some other optimizations (such as keeping a cache of small integers) but this shouldn't affect the measurements much. My personal conclusion: it's not worth optimizing range() at all... --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> "Meten is weten" Replied: Tue, 26 Oct 1993 16:16:06 +0100 Replied: "Kevan Heydon <kevan@Harston.CV.COM> python-list@cwi.nl" Received: from MEDUSA.CV.COM by charon.cwi.nl with SMTP id AA24295 (5.65b/3.11/CWI-Amsterdam); Tue, 26 Oct 1993 15:04:14 +0100 Received: from Harston.CV.COM by medusa.CV.COM (8.6.3/8.5/Medusa) id OAA12676; Tue, 26 Oct 1993 14:04:01 GMT Received: from alrami.Harston.CV.COM by Harston.CV.COM (4.1/SMI-4.1.1/Harston) id AA01229; Tue, 26 Oct 93 14:03:51 GMT Date: Tue, 26 Oct 93 14:03:51 GMT From: Kevan Heydon <kevan@Harston.CV.COM> Message-Id: <9310261403.AA01229@Harston.CV.COM> To: python-list@cwi.nl Subject: Re: Non-list ranges Hello, I have been follwing the thread on Non-list ranges with some interest and would like to mention, as a little diversion, how our in house language (Bacis2) does it. Bacis has the concept of iterator functions that "yield" values to a loop. Hence you define an iterator function such: my_range :- iter(min,max,step) value :- min loop if value > max then break endif yield value value :- value + step endloop enditer with a calling loop such as: loop for var over my_range(1,20,2) sys_show(var) endloop gives: 1 3 5 . . 19 The statement "yield value" suspends the execution of the iterator and passes "value" to the loop that called it. The next time round the calling loop when the iterator is called again the suspended execution resumes after the yield statement. Obviously the calling loop terminates when the iter function terminates. While this type of functionality can be achieved by writing a function to return a list, an iterator function does it without allocating space for a, potentialy very long, list. Could something like this be done in Python? Kevan Heydon Computervision R&D Ltd, Harston, England Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA25604 (5.65b/3.11/CWI-Amsterdam); Tue, 26 Oct 1993 16:16:08 +0100 Received: by voorn.cwi.nl with SMTP id AA09431 (5.65b/3.8/CWI-Amsterdam); Tue, 26 Oct 1993 16:16:07 +0100 Message-Id: <9310261516.AA09431=guido@voorn.cwi.nl> To: Kevan Heydon <kevan@Harston.CV.COM> Cc: python-list@cwi.nl Subject: Re: Non-list ranges In-Reply-To: Your message of "Tue, 26 Oct 1993 14:03:51 MET." <9310261403.AA01229@Harston.CV.COM> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Tue, 26 Oct 1993 16:16:07 +0100 Sender: Guido.van.Rossum@cwi.nl > I have been follwing the thread on Non-list ranges with some > interest and would like to mention, as a little diversion, how our > in house language (Bacis2) does it. > Bacis has the concept of iterator functions that "yield" values to a loop. [...explanation deleted...] > While this type of functionality can be achieved by writing a > function to return a list, an iterator function does it without > allocating space for a, potentialy very long, list. > > Could something like this be done in Python? Interesting point! You can more or less do this with a class. Here is a simple example; it yields the first n elements of the Fibonacci sequence (1, 1, 2, 3, 5, 8, 13, ...): class Fib: # constructor -- argument is length of sequence def __init__(self, n): self.size = n self.reset() def reset(self): self.last_index = 0 self.a = self.b = 1 # return len(self) def __len__(self): return self.size # return self[i] def __getitem__(self, i): if i < self.last_index: self.reset() while i > self.last_index: self.last_index = self.last_index + 1 self.a, self.b = self.b, self.a + self.b return self.a This example tries to behave like a real sequence -- only it is faster when you ask for the items in their natural sequence, hence the reset() method. For iterators that will *only* be used in a for loop, __getitem__ could raise an expression when an item is asked for out of sequence. The catch is that you need to know how many values a particular iterator instance will yield, so you can't use it to simulate an infinite or indefinite sequence. If iterators become popular in Python, it might be possible to redefine the 'for' semantics and extend the interface to sequences to allow for loops over (pseudo-)sequences of indefinite length. But I don't know how much use there is for this, since it is generally just as easy to use a while loop for a loop over an indefinite sequence... --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> To: Kevan Heydon <kevan@Harston.CV.COM> cc: python-list@cwi.nl Subject: Re: Non-list ranges In-reply-to: Your message of "Tue, 26 Oct 1993 14:03:51 MET." <9310261403.AA01229@Harston.CV.COM> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Tue, 26 Oct 1993 16:16:07 +0100 Sender: guido > I have been follwing the thread on Non-list ranges with some > interest and would like to mention, as a little diversion, how our > in house language (Bacis2) does it. > Bacis has the concept of iterator functions that "yield" values to a loop. [...explanation deleted...] > While this type of functionality can be achieved by writing a > function to return a list, an iterator function does it without > allocating space for a, potentialy very long, list. > > Could something like this be done in Python? Interesting point! You can more or less do this with a class. Here is a simple example; it yields the first n elements of the Fibonacci sequence (1, 1, 2, 3, 5, 8, 13, ...): class Fib: # constructor -- argument is length of sequence def __init__(self, n): self.size = n self.reset() def reset(self): self.last_index = 0 self.a = self.b = 1 # return len(self) def __len__(self): return self.size # return self[i] def __getitem__(self, i): if i < self.last_index: self.reset() while i > self.last_index: self.last_index = self.last_index + 1 self.a, self.b = self.b, self.a + self.b return self.a This example tries to behave like a real sequence -- only it is faster when you ask for the items in their natural sequence, hence the reset() method. For iterators that will *only* be used in a for loop, __getitem__ could raise an expression when an item is asked for out of sequence. The catch is that you need to know how many values a particular iterator instance will yield, so you can't use it to simulate an infinite or indefinite sequence. If iterators become popular in Python, it might be possible to redefine the 'for' semantics and extend the interface to sequences to allow for loops over (pseudo-)sequences of indefinite length. But I don't know how much use there is for this, since it is generally just as easy to use a while loop for a loop over an indefinite sequence... --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA28363 (5.65b/3.11/CWI-Amsterdam); Tue, 26 Oct 1993 18:50:04 +0100 Received: from galen.med.virginia.edu by uvaarpa.virginia.edu id aa26439; 26 Oct 93 13:49 EDT Received: by galen.med.Virginia.EDU (5.67a8/1.34) id AA39914; Tue, 26 Oct 1993 13:49:49 -0400 Date: Tue, 26 Oct 1993 13:49:49 -0400 From: "Steven D. Majewski" <sdm7g@galen.med.virginia.edu> Message-Id: <199310261749.AA39914@galen.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: python-list@cwi.nl Subject: For and Non-lists On Oct 26, 16:16, Guido.van.Rossum@cwi.nl wrote: > > > Could something like this be done in Python? > > Interesting point! You can more or less do this with a class. Having tried this sort of thing out before, I'll note that both 'for' and 'in' will work on pseudo-sequence or sequence-like objects that provide __len__(), and __getitem__( index ) methods. > > The catch is that you need to know how many values a particular > iterator instance will yield, so you can't use it to simulate an > infinite or indefinite sequence. > One kludge is just to make 'len()' *LIE*. Return a value that is larger than any realistic value. This implies that your 'for' will break on an appropriate value. ( And you need to raise an exception to break out of an 'in' that is false! ) Also: 'for' appears to call len() method before each call to getitem() method. So you only really have to lie a little bit - only promise one more item. And if you're going to promise one more, you might as well look ahead and cache the next item - then you can *eventually* tell the truth. However, these extra len() calls would seem to be an obvious part of the 'for' to optomize out - so maybe we can't rely on that method continuing to work.(?) Or is that len() a necessary part of the expected semantics of 'for' over an object? ( This also makes it clear why you should use the suggested 'for x in s[:]' when the body is going to modify 's'. ) > If iterators become popular in Python, it might be possible to > redefine the 'for' semantics and extend the interface to sequences to > allow for loops over (pseudo-)sequences of indefinite length. But I > don't know how much use there is for this, since it is generally just > as easy to use a while loop for a loop over an indefinite sequence... How about len() ==> None as a sign of an indefinite length sequence. len() of a non-sequence raises an exception, so the meaning is not overloaded. [ except that: ( None < 0 ), so the test is awkward. ] I find iterators and sequences quite a natural way of dealing with a number of problems. My *other* favorite language, Icon, has co-expressions and co-routines ( the latter much like the basic2 example ) and an 'every' to force full evaluation. I think the object system (IDOL) built on top of Icon uses coexpressions to make objects. ( Tim may be more knowledgable on this - I've never used Idol ) In python, it's the other way around - objects are the primary means of preserving state. I only wish it was a bit easier to create "quick" co-expression like objects. The problem is that there's no easy way to pass THUNKS or unevaluated expressions around in python except as strings to eval/exec. But even if it's not as easy as I'ld like, it's do-able. The other reason I tend to use 'for' over a sequence, has to do with some issues of style I have raised before. Since Python has no C-like assign and test, and I don't like to special case the first assignment at the top of the loop, and even "while 'true' : ... if some_test() : break " , while I think it looks "cleaner", tends to hide the logic of the loop - so if I can at all coerce the logic into "for x in sequence: process(x)", I tend to do so. So if I could think of a good proposal to make 'for' more "object-oriented" ( i.e. behave differently for different objects ), I'ld tend to be in favor of it. But I agree that additional feature's aren't *necessary*, so I don't think they are worth considering unless they can fit in without much trouble. How about something like: for y in every f(x) : meaning to continue to apply f(x) for a new value y. The question is, what is the implied loop exit? y == None or y in ( None, 0, '', [], (,) ) # i.e. any 'false' value or no implied exit, must terminate by a raised signal in f(x) or a explicit test/break in the body of the for. [ Could there be a special "loop break" exception , which is caught and invisibly handled in loops ? ] [Note: Icon handles this by having a special value for failure. ] - Steve Majewski Received: from ogre.cica.indiana.edu by charon.cwi.nl with SMTP id AA29291 (5.65b/3.11/CWI-Amsterdam); Tue, 26 Oct 1993 20:17:09 +0100 Message-Id: <9310261917.AA29291=emo@ogre.cica.indiana.edu@charon.cwi.nl> Received: by ogre.cica.indiana.edu id AA18472; Tue, 26 Oct 1993 14:17:03 -0500 Date: Tue, 26 Oct 1993 14:17:03 -0500 From: Eric Ost <emo@ogre.cica.indiana.edu> To: guido@cwi.nl Subject: python mailing list Greetings Guido, Our mail server went down recently with disk problems and incoming mail was bouncing all over the place. The system should be back to normal now. Sorry for cluttering your mailbox with the returned msgs. Python's great! eric Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA05836 (5.65b/3.11/CWI-Amsterdam); Wed, 27 Oct 1993 07:05:59 +0100 Received: from galen.med.virginia.edu by uvaarpa.virginia.edu id aa01318; 27 Oct 93 2:05 EDT Received: by galen.med.Virginia.EDU (5.67a8/1.34) id AA37093; Wed, 27 Oct 1993 01:39:57 -0400 Date: Wed, 27 Oct 1993 01:39:57 -0400 From: "Steven D. Majewski" <sdm7g@galen.med.virginia.edu> Message-Id: <199310270539.AA37093@galen.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: python-list@cwi.nl Subject: A sequence class that lies about it length Well, while I'm sitting here waiting for restore tapes to finish spinning, I didn't have anything better I could do, so I wrote a test of a sequence class that lies about it's length. Not at all debugged or optimized. The last 5 lines at the end will test it by printing the nominal (sometimes untrue) length, the current length of the internal buffer, and (via pipe to unix 'nl' ) the line numbered lines of 'flines.py' - Steve Majewski <sdm7g@Virginia.EDU> #-------------- # Class Flines # # This is a demonstration/test of a class that "lazily" coerces # the lines of a file into a sequence. # It was written mostly to test the technique of lying about # the length of the sequence by +1, except at the end. # It has the feature that it will continue to try to read # file when it gets to eof, so even if file continues to grow, # so that: # for x in flines_obj: print x[:-1] # will always print whatever is currently available. # So it's actually good for something. # ( But that also means that flines_obj[-1] is very context sensitive! ) # # <sdm7g@Virginia.EDU> # import posix import builtin def rdopen( fname ): # open file or pipe for reading if fname[-1] == '|' : open = posix.popen fname = fname[:-1] else: open = builtin.open return open( fname, 'r' ) class Flines: def _lie( self ): return self._len + 1 def _get1( self ): if self._cache[-1]: self._cache.append( self._file.readline() ) self._len = self._len + 1 else: self._cache[-1] = self._file.readline() def __init__( self, fname ): self._file = rdopen( fname ) self._cache = [ self._file.readline() ] self._len = 1 def __len__( self ): if self._cache[-1]: return self._lie() else: self._get1() if self._cache[-1]: return self._lie() else: return self._len def __getitem__( self, j ): if j < 0 : self._get1() elif j >= self._len : for index in range( self._len, j+1 ): self._get1() return self._cache[j] def __del__(self): self._file.close() def __getslice__( self, i, j ): return self._cache[i:j] F=Flines('nl -ba flines.py|' ) print '# Test me once...' for x in F : print len(F),F._len, x[:-1] print '# Test me twice ... ' for x in F : print len(F),F._len, x[:-1] Received: from meerman.cwi.nl by charon.cwi.nl with SMTP id AA19439 (5.65b/3.11/CWI-Amsterdam); Wed, 27 Oct 1993 21:10:16 +0100 Received: from hopscotch.ksr.com by meermin.cwi.nl with SMTP id AA26001 (5.65b/3.9/CWI-Amsterdam); Wed, 27 Oct 1993 21:10:13 +0100 Received: from ksr.com (frankenstein.ksr.com) by hopscotch.ksr.com with SMTP id AA14820; Wed, 27 Oct 1993 16:08:39 -0400 Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA10270; Wed, 27 Oct 93 16:08:38 EDT Received: by kaos.ksr.com (4.1/KSR-2.0) id AA28740; Wed, 27 Oct 93 16:07:45 EDT Message-Id: <9310272007.AA28740@kaos.ksr.com> To: Guido.van.Rossum@cwi.nl Subject: Re: Optimizing Python Cc: python-list@cwi.nl Date: Wed, 27 Oct 93 16:07:44 -0400 From: Tim Peters <tim@ksr.com> > > [tim] > > In the absence of a > > from something import * > > statement, are there other cases where Python cannot (in principle, & at > > compile time) tell whether the name 'range' denotes the built-in? ... > [guido] > Actually, since built-in names come after module-global names, it is > always possible to sabotage a module by doing something like [importing > the module and fiddling its namespace directly; or via exec or setattr] That's OK; it's possible to worm around that in a compiler, and some of the ways of doing so are even safe <wink>. A first cut would probably like to assume that built-in names denote built-in objects in the absence of a contradictory switch/pragma etc, and that would get 95% of the gain for 5% of the work (in return for being unsafe). would-be-an-interesting-albeit-involved-project-ly y'rs - tim Tim Peters tim@ksr.com not speaking for Kendall Square Research Corp Received: from hopscotch.ksr.com by charon.cwi.nl with SMTP id AA21228 (5.65b/3.11/CWI-Amsterdam); Thu, 28 Oct 1993 00:05:09 +0100 Received: from ksr.com (frankenstein.ksr.com) by hopscotch.ksr.com with SMTP id AA16475; Wed, 27 Oct 1993 19:04:48 -0400 Received: from kaos.ksr.com by ksr.com (4.0/SMI-3.2) id AA12323; Wed, 27 Oct 93 19:04:51 EDT Received: by kaos.ksr.com (4.1/KSR-2.0) id AA08202; Wed, 27 Oct 93 19:04:46 EDT Message-Id: <9310272304.AA08202@kaos.ksr.com> To: python-list@cwi.nl Subject: Re: Non-list ranges; iterators in general Date: Wed, 27 Oct 93 19:04:45 -0400 From: Tim Peters <tim@ksr.com> > [guido times a range object implementation with discouraging results] > ... > My personal conclusion: it's not worth optimizing range() at all... No argument here -- & very interesting. > [discussion of iterators] > [steve] > ... > [Note: Icon handles this [breaking out of an iterator loop] by having a > special value for failure. ] Well, it's kinda _implemented_ that way, but the user doesn't (need to) know anything about that. _Every_ expression in Icon generates a sequence of 0 or more results, and to say that an Icon expression "fails" is the same as saying the expression has an empty (length 0) result sequence. The point is that iterators fit naturally into such a scheme, since they're just one more expression that yields 0 or more results. It's hard to see how to support this in a general way without buying into the whole co-routine business, and that seems like a lot of new machinery for Python. People might be interested in seeing how this works in Icon. So here's an Icon version of the Fibonacci example. Abstractly, it looks much like Basic2's approach: procedure main() every x := fib() do if x < 500 then write( x ) else break end procedure fib() local a, b, sum a := b := 1 # vanilla multiple assignment repeat { # infinite loop suspend a # 'suspend' sez to return the value, & also allow resuming sum := a + b a := b b := sum } end That prints 1 1 2 3 5 8 13 21 34 55 89 144 233 377 The successive generation of fib's values is driven by the "every" control structure. A kind of closure can also be created by the "create" construct, and resumed as desired with the invocation operator "@"; e.g., procedure main() thunk := create fib() write( @thunk ) write( @thunk ) write( @thunk ) write( @thunk ) end prints 1 1 2 3 More general mechanisms exist for passing control in arbitary co-routine fashion, etc. This is all very slick in theory, but in my experience Icon's implementation of these features is burdensome & buggy. Icon was designed for exploring new language ideas, so that's fine for Icon. I don't think it fits Python's worldview, though. > [ Could there be a special "loop break" exception , > which is caught and invisibly handled in loops ? ] That seems the cleanest way to get the most useful part of the functionality in Python, but I worry more about how much hair it would add to permit suspending & resuming the "sequence" part of "for thing in sequence:". > [steve] > ... > So if I could think of a good proposal to make 'for' more "object- > oriented" ( i.e. behave differently for different objects ), I'ld tend > to be in favor of it. But I agree that additional feature's aren't > *necessary*, so I don't think they are worth considering unless they > can fit in without much trouble. Agreed on all counts. harmoniously y'rs - tim Tim Peters tim@ksr.com not speaking for Kendall Square Research Corp Received: from pl122e.eecs.lehigh.edu by charon.cwi.nl with SMTP id AA23087 (5.65b/3.11/CWI-Amsterdam); Thu, 28 Oct 1993 03:17:53 +0100 Received: by PL122e.EECS.Lehigh.EDU (5.61/1.34) id AA11088; Wed, 27 Oct 93 22:04:49 -0400 Date: Wed, 27 Oct 93 22:04:49 -0400 From: tb06@PL122e.EECS.Lehigh.EDU (TERRENCE BRANNON) Message-Id: <9310280204.AA11088@PL122e.EECS.Lehigh.EDU> To: python-list@cwi.nl Subject: final pre-Usenet posting of "Survey of Interp. Lang." This is the final posting of this paper before it goes to Usenet. Please email me any input you have: \documentstyle{report} \pagestyle{headings} \begin{document} \title { Survey of Quick Interpreted Languages } \author { Terrence Monroe Brannon \\ PO Box 5027 \\ Bethlehem, PA 18015 \\ $tb06@pl122e.eecs.lehigh.edu$ } \maketitle \tableofcontents \part {Introduction and Conclusion} The purpose of this report is to expose people to several languages which can cutdown/eliminate shell programming and C programming. All of these languages are quick interpreted languages which can do things in a few lines which might take hundreds of lines of C/shell code. They typically have all of the following features: \begin {itemize} \item The ability to modify the source code at runtime, adding new procedures or modifying old ones. \item An efficiently hashed associative data type. \item Loose typing \item The interpreter has no preconceptions about each sentence (valid syntactic phrase) it will execute. In other words it knows nothing (return type, datatype) ahead of time about the data or functions in memory. \end {itemize} These languages are evaluated in terms of the three things that any programmer desires from a language: power, speed, and ease of use. Power means a wealth of libraries for any task needed resulting in less time required for developing/protoyping software. Speed means execution speed. Ease of use includes how well documented the language is, how much support there is for problems with the language, and how cleanly extensible the language is. \section {The Languages} \subsection {Lisp: Emacs version} The Emacs Lisp editor has a core of functions including an interpreter written C to return Lisp Objects. On top of this a number of Lisp Functions for common tasks such as editing, buffering, process control, string handling, user interaction/input completion, and mathematics have been coded in C. As a result, virtually Anything Emacs does is done by a callable lisp function which means you can write programs to take advantage of this power. But you can only do it inside of Emacs Lisp for the most part. The two work arounds are: (1) use emacs-server.el which allows Emacs to send/receive on sockets, message queues and pipes or (2) use emacs server mode. (3) For my M.S. thesis, I developed a C library which allows Tcl and GNU Smalltalk to invoke Emacs' processes and send the process Lisp forms for evaluation and then have the data converted back into a format useable by the calling language. Emacs can interact with other programs is through its batch mode which is callable from C or shell scripts. Also, Emacs can start up external programs and talk with them via process objects synchronously or asynchronously. Danial LaLiberte wrote an Emacs interface to an incremental parser that runs simultaneously with Emacs and has bidirectional communication with Emacs. You may obtain Emacs Lisp via the following ftp site: \begin {itemize} \item "/anonymous@src.doc.ic.ac.uk:/pub/gnu" \item "/anonymous@prep.ai.mit.edu:/pub/gnu" \end {itemize} \subsection {Perl} Combines the best features of awk, sed, and shell programming. The latest version can be embedded in C programs. It is also easy to call from the shell. Perl can be linked with external C libraries, such as curses or database accessing libraries, like oracle or sybase, making for easy access to screen-based form programs to deal with your dbase. Perl may be obtained from the following ftp sites: \begin {itemize} \item "/anonymous@convex.com:/pub/perl" \item "/anonymous@archive.cs.ruu.nl:/DOC" \end {itemize} \subsection {Python} An object-oriented interpreted language. Callable from C as well as the shell. Interpretation may be sidestepped through the use of the byte-compiler on files. Python played a major role in testing Amoeba, a distributed operating system developed at CWI. Python has been chosen as one of the extension languages for MADE, a multimedia application development environment being designed and built for ESPRIT (an EC programme for cooperative computer science research) together with several European companies. Several companies have significant interest in Python for products and/or internal development; amongst these are XVT, Sunrise Software, Island Software, VI Corporation, and Cabletron. It's central goal is to provide the best of both worlds: the dynamic nature of scripting languages like Perl/TCL/REXX, but also support for general programming found in the more traditional languages like Icon, C, Modula,... Python resembles other scripting languages a number of ways: - dynamic, interpretive, interactive nature - no explicit compile or link steps needed - no type declarations (it's dynamically typed) - high-level operators ('in', concatenation, etc) - automatic memory allocation/deallocation (no 'pointers') - high level objects: lists, tuples, strings, associative arrays - programs can construct and execute program code using strings - very fast edit/compile/run cycle; no static linking - well-defined interface to and from C functions and data - well-defined ways to add C modules to the system and language Python's features that make it useful for serious programming: - it's object-oriented; it has a simplified subset of C++'s 'class' facility, made more useful by python's dynamic typing; the language is object-oriented from the ground up (rather than being an add-on, as in C++) - it supports modules (imported packages, as in Modula-3); modules replace C's 'include' files and linking, and allow for multiple-module systems, code sharing, etc.; - it has a good exception handling system (a 'try' statement, and a 'raise' statement, with user-defined exceptions); - it's orthogonal; everything is a first-class object in the language (functions, modules, classes, class instance methods...) and can be assigned/passed and used generically; - it's fairly run-time secure; it does many run-time checks like index-out-of-bounds, etc., that C usually doesn't; - it has general data structuring support; Python lists are heterogeneous, variable length, nestable, support slicing, concatenation, etc., and come into existance and are reclaimed automatically; strings and dictionaries are similarly general; - it's got a symbolic debugger and profiler (written in python, of course..), and an interactive command-line interface; as in Lisp, you can enter code and test functions in isolation, from the interactive command line (even linked C functions); - it has a large library of built-in modules; it has support for sockets, regular expressions, posix bindings, etc. - it supports dynamic loading of C modules on many platforms; - it has a readable syntax; python code looks like normal programming languages; tcl and perl can be very unreadable (IMHO; what was that joke about Perl looking the same after rot13..); python's syntax is simple, and statement based; Of course, Python isn't perfect, but it's a good compromise betweem scripting languages and traditional ones, and so is widely applicable. 'Perfect' languages aren't always useful for real-world tasks (Prolog, for example), and languages at either extreme are not useful in the other domain (C is poor for shell coding and prototyping, and awk is useless for large systems design; Python does both well). For example, I've used Python successfully for a 4K line expert system shell project; it would have been at least twice as large in C, and would have been very difficult in TCL or Perl. Python uses an indentation-based syntax which may seem unusual at first to C coders, but after using it I have found it to be very handy, since there's less to type. [I now forget to type '\}' in my C code, and am busy calculating how much time I wasted typing all those '\}', 'END', etc., just to pander to 'brain-dead' C/Pascal compilers :-)]. Python is available from the following sites: \begin {itemize} \item "/anonymous@ftp.cwi.nl:/pub" \item "/anonymous@gatekeeper.dec.com:/pub/plan/python/cwi" \item "/anonymous@ftp.uu.net:/languages/python" \item "/anonymous@wuarchive.wustl.edu:/pub" \end {itemize} To get on the mailing list mail {\tt python-list-request@cwi.nl}. \subsection {Tcl} Tcl itself is a deceptively simple string-oriented language intended to be transparently extensible in C or Tcl. Tcl has been extended to make use of many typically non-unified systems and protocols such as SQL, curses, ToolTalk, and most notably, X-Windows. Tcl can do a 5 page X-Windows program in *2* lines and more. >From having programming in Tcl extensively, I have noticed two very useful aspects about Tcl. First, Tcl is a modeless language, meaning that it does not enforce any particular programming paradigm such as functional, logic, or object-oriented. As a result, it is very easy to switch between any of the above modes during the same program execution. Two well-designed object systems (incr Tcl and TheObjects) exist for Tcl. The author is currently finding embedding a Prolog interpreter into Tcl a simple task (much easier than the Pascal pseudo-code). The second thing about Tcl is that all commands and data (with the exception of associative arrays and C source code for use in Tcl) are nothing but strings. As a result, programs and data are highly interchangeable. Tcl contains 3 datatypes -- a word (a collection of ascii characters), a list (a whitespace separated collection of words) and associative arrays. Since lists are nothing but strings, they are mutable by both string and ``list'' operations, where list operations are nothing but string operations which regard whitespace as word separators. Tcl has been ported to most unix-like systems (Sun, DEC, Silicon Graphics, System 5, the free Intel unix-alikes, etc.), VMS, Amiga, MS-DOS, MACOS, GS/OS, Vxworks, and a number of other operating systems. Tcl is available at the following ftp sites: \begin {itemize} \item "/anonymous@sprite.berkeley.edu:/tcl" \item "/anonymous@harbor.ecn.purdue.edu:/pub/tcl" \end {itemize} \section {Acknowledgements} \begin {description} \item [Per Abramsen] For his source code contributions. \item [Tom Christiansen] For his Perl source code for this paper and also his general comments. \item [Lance Ellinghouse] For his Python source code and critique of this paper. \item [Bill Janssen] For his additions to this paper. \item [Daniel Laliberte] For his excellent work with the Free Software Foundation including co-authorship of the Emacs Lisp Reference Manual and also his comments on this paper. \item [Karl Lehenbauer] For co-authorship of Extended Tcl and for his source code contributions to this paper. \item [Michael Winikoff] for his critique. \item [Larry Virden] For his tireless work on the Tcl FAQ (which was the first time I had ever heard of Tcl) and his critque of this paper. \end {description} \subsection {Important Papers / People} \begin {description} \item [Catalog of Free Compilers and Interpreters] This document attempts to catalog freely availiable compilers, interpreters, libraries, and language tools. Available via anonymous ftp from: {\tt /anonymous@idiom.berkeley.ca.us:/pub/compilers-list/FreeCompilers*} \item [Language List] Collected information on about 2100 computer languages, past and present. Available from {\tt /anonymous@primost.cs.wisc.edu:pub/comp.compilers/LanguageList*} {\tt /anonymous@idiom.berkeley.ca.us: pub/compilers-list/LanguageList*}. You can also access a hypertext version of the Language List via xmosaic from the HTTP server: {\tt http://cui\_www.unige.ch} \end {description} \section {The Future} \subsection {More Languages} \subsection {More Examples and Tests} \subsection {Multiple Computer Language Programming} Expression of mathematics in Tcl is cumbersome yet X11 graphics is very very easy. Perl has excellent string and manipulation tools and a ton of sysadmin utilities written in it. The bottom line is that all of these languages have powerful tools ready to use. Each language also has its weak points. Instead of being stuck in each language and slaving through its weakness (or lack of a certain utility), one should be able to fire up an interpreter in any of these other languages and let it perform on it strong points and return the answer. I expect this type of hybrid programming to become almost necessary with excellent packages and large being written for each langauge. For my M.S. Thesis, I developed a C library which allows for simulataneous programming in C, Emacs Lisp, Smalltalk and Tcl. \subsection {More Software} A trans-language browser. If you see that a Perl script has been written to traverse a directory tree and count the number of files ending in .o whose age is more than 20 days but you are not a Perl programmer, that Perl script should become and OBJECT to which you SEND a message to get that work done. \subsection {Is Interpreted Really Slower?} I some cases compiled code is really compiled code performing certain interpretive tasks. As a result, an interpreted language (which is really just a C program performing syntax-directed tasks) may perform as fast or faster than compiled code trying to perform interpreted tasks. Although not currently detailed in this survey, an excellent example of a language optimized for particular interpreted tasks is Prolog. Consider a program typically done in an introductory programming class: maintain a student gradebook and be able to collect information from the gradebook based on certain criteria such as year in school and overall average. Analysis of this program reveals three major tasks: {\it hashing} of students by a unique key, {\it searching} the hashed space, {\it collecting} related students based on specified criteria. To anyone experienced in Prolog, there is no question that a Prolog program to perform this task will be far shorter than the corresponding C program. In addition, because there is only one method for handling each of the major tasks of the program, the Prolog interpreter can make use of its optimized methods for handling each of these tasks. \footnote{The only method of hashing is by assertion of clauses. The only method of searching the clauses in a Prolog program is by unification. The only method of collection of numerous clauses is by recursive list generation.} Therefore in cases where one is trying to model a changing, evolving, non-deterministic situation, an interpreted language is best used. \part {Power} \chapter {Graphics} \section{Emacs Lisp} \section{Perl} \section{Python} \subsection {Significant Extensions} Python has full support for both X11R4/Motif and through the use of the STDWIN paradigm, the same source code can do graphics in the following systems: \begin{enumerate} \item X-windows \item Macintosh using either Think C 4.02 or MPW C 2.02 \item Atari ST \item DOS \item Silicon Graphics SGI workstations \end{enumerate} This approach allows flexibility but means that no one graphics system's potential is maximized. \section{Tcl} \subsection {Significant Extensions} \begin{description} \item[TD\_CAD] A drawing program \item[VOGLE] 3D rendering, fonts \item[TSipp] Tcl interface to the SIPP 3-D rendering package. \end{description} \chapter {User Interface Building} \section {Emacs Lisp} Emacs 19 has popup menus and multiple windows. The ability to synchronously and asynchronously control processes it to use Tcl's WAFE. \section {Perl} Again none interally, but the author of WAFE, the tcl/tk graphic interpreter wrote all of his example programs in Perl (wafemail, wafenews, wafeftp). Certainly perl can issue external commands (inferior processes in lisp parlance). There is also a version of guiperl I've seen Larry demo for me, so there's at least proof-of-concept that you can link in the X libs. Whether it will come out with perl5 I don't know. \section {Python} STDWIN also handles user interface development tasks. \subsection {Significant Extensions} \begin {description} \item [EZD] Joel Bartlett's very nice WAFE-style system (very nice, check it out!). *** More comments are needed here... *** \end {description} \section {Tcl} Power is the word. Tcl has numerous user-contributed widgets including photo widgets, bar graph widgets, editable text widgets, pixmap widgets and much more. \subsection {Significant Extensions} \begin{description} \item[XF] Menu-driven user interface builder \item[TkSteal] Allows for a Tk program to have an Emacs widget or a Ghostscript widget. \item[Pixmap] A color pixmap editor written in Tcl/Tk \item[PhotoWidget] A photo widget for Tk. \item[WAFE] {\it W}idget {\it A}thena {\it F}ront {\it E}nd. Implemented in Tcl, this package allows for the same generic graphic commands to be used to develop user interfaces regardless of what language you are programming in. All you need to do is interface to WAFE from your language. \item[xy-graph] Includes a Hypertext widget. This means that regardless of what stream of information comes at your Tcl program, you can create windows and paths through the stream on the fly. A major example of the hypertext widget is Joseph Wang's World Wide Web Hypertext browser. \end{description} \chapter {String Handling} \section {Emacs Lisp} Strong. Many good string handling functions for operation on buffers as well as string. Search replace backward and forward with regexps. Many good string handling functions are found in tree-dired.el in gmhist*.el. As well as in ange-ftp.el. \section {Perl} Very strong. String-handling is one of Perl's strongest features: they are quite powerful and extensive. Strings can be as long as you want, and contain binary data and nulls. This works: \begin{verbatim} $kernel = `cat /vmunix`; \end{verbatim} Perl has a wealth of string-accessing functions, including matching, substitution, transliteration, splitting, and direct substring accessing. Strings and numbers are interchangeable. The regexps are a superset of other regexp syntaxes, with extensions. Parsing is very easy: \begin{verbatim} ($name, $number, $host) = /(\w+)=(\d+)( from @(\w+))?/; \end{verbatim} Subexpressions can nest, and be arbitrarily deep: you don't have to stop with \\9, but can keep going. Perl's substitution operator works like sed's: \begin{verbatim} s/foo/bar; \end{verbatim} or \begin{verbatim} $a =~ s/foo/bar/g; \end{verbatim} but can do much more, like: \begin{verbatim} s/(\d+)/sprintf("0x%08x", $1)/ge; \end{verbatim} to find all the numbers in the pattern space and replace them with the hex representation of the same. It has other powerful features I don't have time or space to go into. Perl also lets you treat strings as raw bitwise data, so \begin{verbatim} substr($a,0,3) &= "\177\177\177"; \end{verbatim} would clear the high bits on the first 3 bytes of \$a. You can also access strings bitwise, say, to check the $2456$th bit of a string. \section {Python} It has a string module, regexp module, and regsub module. It has all the string search and replace capabilities of Emacs. \section {Tcl} Everything in Tcl is a string. It is very easy to map certain string-intensive applications to Tcl. For example, I wrote a program to do parallel library database searches in Tcl in about two weeks. Ranking the 4 languages in terms of how easy it would have been: Tcl, Python, Emacs, and I cant say about Perl because I gave up on Perl quickly after buying the book and seeing all those registers and the confusing context-intensive syntax. \chapter {Unix / Internet Programming} \section {Emacs Lisp} Has specialized modes for controlling Common Lisp and other lisps to facilitate debugging, execution, and programming. Has shell modes with command history. Has an excellent ftp program (ange-ftp). Can asynchronously or synchronously call the shell and store the output in a buffer or string. Can filter output from a process. However, the filtering is somewhat hairy because you cannot be sure of the packet size that the data will arrive in. In other words, it is easy to open a pipe with Perl/Python/Tcl and just read lines at a time but you have to write an accumulator function to do this in Emacs Lisp. However, the interactor mode for GNU Smalltalk has an excellent accumulator function that you could use in your own code. Dan LaLiberte disagrees with the difficulty of accumulating input from a process that Emacs has spawned. He says: ``An accumulator of whole lines could be written in Emacs Lisp with not much problem. I'd be surprised if no one has done so yet.'' However, until I see it, I stand by my above statement. \subsection {Significant Extensions} \begin {description} \item[VM] A mail reader that does everything that I need. \item[Gnus] A Usenet reader that can save articles to mail folders for later recall. I often save articles in Gnus and later read them using VM. \item[Ange-FTP] An excellent ftp utility which allows transparent file access/modification with the ease of a few keystrokes. \item[Tree Dired] Allows you to scroll through directories and copy, edit, remove, view files. And more \end {description} \section {Perl} Perl has all the process control primitives available to you from C, plus higher level constructs as well. It's easy to open a pipe to or from another process. You can even open a pipe to an implicitly forked version of yourself. Standard Perl library routines allow bidirectional pipes and running things over a pty via a package that works much like Don Libes's Expect, save that it uses Perl instead of tcl as an extension language. Perl can also access all the socket and ipc functions on your system without calling a program to do it. \subsection {Significant Extensions} ??**?? \section {Python} Python's process control is at least as strong as Perl's. In addition, it supports threads (!), so that some of the operations you have to do in another process, using Tcl or Perl, you can do in another thread, in Python. Python has a Posix and a generic OS module to handle this type of thing. \subsection {Significant Extensions} \begin {description} \item[ftplib.py] \item[nntplib.py] \end {description} \section {Tcl} \subsection {Significant Extensions} \begin {description} \item[Expect] Due to an extension added to Tcl, process control in Tcl is a snap. A Tcl package by Don Libes called Expect allows the programmer to specify a set of expected regexps from the process and what to do upon the receipt of the process output. Several of his papers including "expect: Curing Those Uncontrollable Fits of Interaction" available in postscript format for anonymous ftp from durer.cme.nist.giv in pub/expect. \item[Artcls] A graphic Usenet newsreader. \item[TkWWW] A Tk world-wide web browser. \end {description} \chapter {Other} \section {Emacs Lisp} \begin{description} \item[Folding Mode] Allows for hierarchical editing of structured text files. I use it all the time. You can move through and edit any document (program, LaTeX file, whatever) much faster using folding mode. \item[EDB] full featured database \item[AUC-TeX] Allows you to do anything you would want to do with TeX/LaTeX from an Emacs buffer quickly and easily. \item[Calc] The poor man's Mathematica. Includes rewrite rules and functionality on the order of the HP-28. \item[VIP] vi emulation for emacs \item[Calendar/Diary] Calendar and appointment manager within Emacs \item[Hyperbole] Extensible hypertext management system within Emacs. \end{description} \section {Perl} Having been publicly available for six years now, Perl has a truly huge body of code already written for it. I couldn't begin to document all of them. More than any other language listed herein, it is the tool of choice for Unix system administrators. Perl comes with a symbolic debugger, a bunch of libraries, various tools, and and numerous example programs, but that's just the start. \section {Python} \begin {description} \item[CMIFed] An authoring environment for transportable, distributed hypermedia presentations. It consists of at least 20,000 lines of Python and 4,000 lines of C extensions. (A paper by Guido von Rossum and others about it has appeared in the proceedings of the ACM Multimedia '93 conference.) \item[MCC] A teleconferencing tool written in Python. Still under development. \end {description} \section {Tcl} \begin {description} \item[Objectify] Turns C++ classes into Tcl objects. \end {description} \chapter {Sample Programs} \section {User Interface Design} \subsection {Hello, world} Write a program to run under X-Windows which opens a window and prints {\tt "Hello, World"} in it. Those interested in highly portable graphic/user interface software should note that the only language capable of doing this program on a graphic windowing system beyond X-Windows is Python. %%%4.1. \subsection {Emacs Lisp} \subsubsection {Emacs Lisp} \begin{verbatim} (defun hello-world () ; FSF Emacs 19 only. ``Open new frame with a friendly greeting.'' (switch-to-buffer-other-frame ``*hello world*'') (insert ``Hello, World'')) \end{verbatim} %%%4.2. \subsection {Perl} \subsubsection {Perl} \begin{verbatim} I'd just talk to Wafe or Stdwin. Or call xterm. :-) \end{verbatim} \subsubsection {Tcl} \begin{verbatim} button .hello -text {Hello, World} -command {exit} pack append . .hello {top} \end{verbatim} \section {String Handling} \subsection {String Test} Given a file with 4 occurrences of the string "Hello Bob" find the file, replace the last 3 occurrences of "Hello Bob" with "Hi James" and save the file. The double quotation marks are for delineation purposes only. \subsubsection {Emacs Lisp} \begin{verbatim} (defun Bob-meet-James (file) ``Replace all `Hello Bob' with `Hi James' in FILE except the first.'' (save-excursion (find-file file) (goto-char (point-min)) ; We might already be editing it... (search-forward ``Hello Bob'') (while (search-forward ``Hello Bob'' nil t) (replace-match ``Hi James'')) (save-buffer))) \end{verbatim} \subsubsection {Perl} \begin{verbatim} # the orig file will be in file.BAK -- if you don't want a backup, # use just -i. # remember that s//foo/ will match the last match perl -i.BAK -p -e '/Hello Bob/ && $seen++ && s//Hi James/g' or perl thisprog < file.in > file.out #!/usr/bin/perl while (<>) { if (/Hello Bob/ && $seen++) { s//Hi James/g; } print; } \end{verbatim} \subsubsection {Python} \begin{verbatim} #! /usr/local/bin/python import strop fp = open('testFile','r') lines = fp.readlines() # read all lines in and seperate on \n's fp.close() fp = open('testFile','w') for indx in range(0,len(lines)-4,4): fp.write('\n'+lines[indx]+'::'+linex[indx+1]+'::'+lines[indx+2]) fp.close() \end{verbatim} OR \begin{verbatim} Hello, Bob (I think; I didn't actually try it): #!/usr/bin/python def sub_in_file(file): import regsub import string seen = None fp = open(file, 'r+') lines = fp.readlines() fp.seek(0, 0) for line in lines: if seen: regsub.gsub('Hello Bob', 'Hi James', line) else: seen = (string.find (line, 'Hello Bob') >= 0) fp.write(line) import sys sub_in_file(sys.argv[1]) \end{verbatim} \subsubsection {Tcl} \begin{verbatim} set fdIn [open testFile r] set contents [read $fdIn] regexp -indices "Hello Bob" $contents matches regsub -all "Hello Bob" \ [string range $contents [expr [lindex $matches 1]+1] end] \ "Hi James" result close $fdIn set fdOut [open testFile w] puts $fdOut [string range $contents 0 [lindex $matches 1]]$result \ nonewline close $fdOut exit \end{verbatim} \subsection {String Test 2} A lengthy file has been entered with records of the form: \begin{verbatim} <\n>NAME<\n>ADDRESS<\n>PHONE<\n>---------- \end{verbatim} where \begin{verbatim}<\n>\end{verbatim} represents a line feed and the \begin{verbatim}----------- \end{verbatim} is used to separate records. Convert all entries in the file to a new format of the form: \begin{verbatim}<\n>NAME::ADDRESS::PHONE} \end{verbatim} \subsubsection {Emacs Lisp} \begin{verbatim} (defun newline-to-double-colon () ``Convert current buffer from old style to new style address book format.'' (goto-char (point-min)) (while (re-search-forward ``\n\\([^\n]*\\)\n\\([^\n]*\\)\n\\([^\n]*\\)\n----------'' nil t) (replace-match ``\n\\1::\\2::\\3''))) \end{verbatim} \subsubsection {Perl} \begin{verbatim} #!/usr/bin/perl $/ = "\n----------"; # set record separator while (<>) { # read a record s!$/$!!; # remove record terminator s/^\n//; # trim first line feed s/\n/::/g; # turn rest into double dolon print "\n"; # new record starts with \n print; # output current pattern space } # Did you know that the last record in the file will no longer # have a terminating newline? Make sure the others get this right. \end{verbatim} \subsubsection {Tcl} \begin{verbatim} set fdIn [open testFile r] set contents [read $fdIn] regsub -all "^\n" $contents "" contents regsub -all "\n" $contents "::" contents regsub -all "::----------::" $contents "\n" contents close $fdIn set fdOut [open testFile w] puts $fdOut $contents nonewline close $fdOut exit \end{verbatim} \subsection {Parsing a Prolog Structure for Logical Variables} A Prolog structure consists of a {\it functor,} open parenthesis, a series of comma-separated {\it terms,} which may be either constants or logical variables and a close parenthesis. Here is an example of a structure with a constant named {\tt baker} and two logical variables named {\tt CHARLIE} and {\it FRANCE}. \begin {verbatim} able(baker,CHARLIE,FRANCE) \end{verbatim} Write a procedure that when given a list of structures (structures separated by whitespace or tabs) will print out all of the logical variables in each structure, also printing out each corresponding functor. For example, given the above structure the output would be: \begin {verbatim} functor: able logical variables: CHARLIE FRANCE \end{verbatim} \subsubsection {Emacs Lisp} \subsubsection {Perl} \subsubsection {Python} \subsubsection {Tcl} \begin {verbatim} proc datalog_logical_variables_in_clause {clause} { foreach structure $clause { set S [string trimright $structure ")"] set F [lrange [split $S "("] 1 end] set S [split $F ","] puts "functor: [lindex $F 0] logical variables: $S" } } \end{verbatim} \subsection {Hofstadter's MIU Formal System} Basically this is a test of string concatenation. We start with one initial string and drop it in a bucket (any appropriate datatype from your language is fine). Then we apply each applicable rule of the system to all strings in the bucket and add the results of each application to the bucket. We perform the rule application five times. The only characters in a string are M, I, and U (just the letters not the commas). Here are the rules: \begin {enumerate} \item If a string S has I as its last letter, you can add on a U at the end of S, creating a new string. Example: $ S == MII. S_{new} == MIIU. $ \item Suppose string S is of the form Mx. Then you may create a string of the form Mxx from S. Example: $ S == MIU. S_{new} == MIUIU. $ \item If the substring III appears in S, then III may be replaced by U. Multiple occurrences of III result in multiple new strings. Example: $ S == MIIII. S_{new1} == MIU. S_{new2} == MUI $ \item If the substring UU occurs inside S, then the first occurence may be deleted. Example: $ S == MUU. S_{new} == M. $ \end {enumerate} \subsection {Filtering a Printerleaf File} I once had a dump of a file of Interleaf which looked like this: \begin {verbatim} \\377Parallelized\\266the\\266expectation \\266maximization\\266algorithm.\\266This\\266algorithm\\266is\\266used \end{verbatim} I wanted to do the following: \begin {itemize} \item Simply output alphanumeric characters \item Simply output linefeeds \item Otherwise output a space \end {itemize} So I wrote the following C program: \begin {verbatim} #include <stdio.h> main (int argc , char *argv[]) { FILE * fp ; char c ; fp = fopen (argv[1],"r") ; printf ("argv[1]: %s \n", argv[1]) ; while ((c = getc (fp)) != EOF) { if (isalnum(c)) { putchar (c) ; } else { if (c == 10) { putchar (c) ; } else { putchar (32) ; } } } } \end{verbatim} \section {Unix/Internet Programming} \subsection {Count files in a Directory} Write a program to count the number of files in the current directory. \subsubsection {Emacs Lisp} \begin{verbatim} (defun current-directory-size () ``Number of files in the current directory.'' (length (directory-files ``.'')) \end{verbatim} \subsubsection {Perl} \begin{verbatim} #!/usr/bin/perl $count = @files = <*>; print "Directory file count: $count\n"; #!/usr/bin/perl $count++ while <*>; print "Directory file count: $count\n"; #!/usr/bin/perl print "Directory file count:", `ls | wc -l`; # those didn't have dot files. if you want dot files, # use <* .*> instead. #!/usr/bin/perl opendir(DOT, '.'); $count = @files = readdir(DOT); print "Directory file count: $count\n"; #!/usr/bin/perl opendir(DOT, '.'); $count++ while readdir(DOT); print "Directory file count: $count\n"; \end{verbatim} \subsubsection {Python} \begin {verbatim} def current_directory_size(): import os return len(os.listdir('.')) \end{verbatim} \subsubsection{Tcl} \begin{verbatim} set count [ls | wc -l] \end{verbatim} \subsection {Automated FTP file transfer} Transfer the file {\tt tension.tex} from the internet host {\tt lambda.barnes.edu} in your home directory to the internet host {\tt calculus.au} to the directory {\tt pub/public} with the file having the new name {\tt noneed.tex}. \subsubsection {Emacs Lisp} \begin {verbatim} (copy-file "/anonymous@lambda.barnes.edu:tension.tex" "/anonymous@calculus.au:pub/public/noneed.tex") \end{verbatim} \subsubsection {Perl} \subsubsection {Python} \begin {verbatim} path = 'lambda.barnes.edu:tesion.tex:tension.tex' fetch (path) \end{verbatim} \subsection {Significant Extensions} \begin {description} \item[nntplib.py] \item[ftplib.py] \item[rsa/md5] encryption \item[xdr.py] Sun's ONC XDR interface \item[rpc.py] Sun's ONC, portmapper, TCP/IP interface (NFS, etc examples) \item[mimetools] Tools used for MIME reading/writing of messages \item[jpeg.py] JPEG/JFIF compression/decompression routines \end {description} \subsubsection {Tcl} \section {Other} \subsection {Count lines in a File} Open up a file named {\tt bozak.foo} and print the number of lines in it to stdout. \chapter {Programmer Support} \section {Learning Curve for Language} \subsection{Emacs Lisp} The best. Has a debugger. Since you are in Emacs, you can immediately test whatever you are writing. Documentation on every function and variable in memory is available in 2 keypresses. The tags system allows you to jump to functions and global variable declarations without knowing which file they are in. The Usenet group {\tt gnu.emacs.help} exists. The GNU Emacs Lisp manual exists. \subsection{Perl} I would say strong. To use Perl, you only need to know a little bit to start to use it. The interactive debugger allows you to type any kind of Perl code you want and get an immediate answer, as well as providing standard sym debugger capabilities such as breakpoints, single-stepping, and stack tracebacks. Other tools available but not included with the Perl src kit include profilers, tags generators, cross referencers, and tools to assemble large Perl programs using makefiles and a lintlike checker. Other tools provide perl-mode for vi as well as tightly coupling the debugger with a slave vi session that autopositions by file and line. The newsgroup {\tt comp.lang.perl} exists. The Perl book by Larry Wall is out. \subsection{Python} Good. The language is VERY regular and very powerful. You have seperate name spaces that allow reuse and an OO design of your applications/scripts. There are HUNDREDS of support modules you can import. There is a mailing list that you may join by mailing {\tt guido@cwi.nl}. Several manuals for using Python exist. Note that there is a GNU Emacs mode for Python, as well as a special subprocess mode for it. There are a couple of debuggers shipped with the Python library, one windowing and one command-line-like. \subsection{Tcl} The language is very consistent --- every line is started with a command which is the name of a Tcl or C function. The rest of the line is arguments to the Tcl or C function. The newsgroup {\tt comp.lang.tcl} exists. The Tcl books is due out soon. A version is currently available via anonymous ftp from {\tt /anonymous@harbor.ecn.purdue.edu:pub/tcl/sprite-mirror}. \section {Test Suite} \subsection{Emacs Lisp} Well, if you compile Emacs then all core source code that Emacs needs will run. However one of its several hundred functions and commands that Emacs itself does not depend on might fail when a user tries to use it and no test suite exists for these non-core commands. \subsection{Perl} Exhaustive test suite. \subsection{Python} Exhaustive test suite \subsection{Tcl} Exhaustive test suite \chapter{Extensibility} Extensibility is the ability to add a new keyword or data type to the language in BOTH the language and C language. \section {Emacs Lisp} Extending Emacs with new Lisp code is very easy. Writing additional C code to be added to Emacs is tedious for several reasons: \begin {enumerate} \item The GNU Emacs Manual does not attempt to give comprehensive information on how to extend Emacs in C. \item You must guess at the correct size of a variable called {\tt PURESIZE} in order to be sure that Emacs allocates enough memory for itself when it dumps itself with the additional source code. \item The {\tt GCPRO} macros are only able to protect a maximum of 4 variables. \end {enumerate} \section {Perl} I am not a Perl programmer and really have no right to say anything here, but having bought the Perl book, I noticed that the language is very context-sensitive and has a grammar covering several pages. In contrast, the relation of syntax to semantics for these other languages is simple and learnable in about 5 minutes. You can extend Perl through linking with C routines. The example with the perl kit explains how to do this for the curses library, but can be done for many other applications as well. This is adding new function calls. What you would probably do is define a package and use acccessor functions. I did this to allow perl user's to get at C struct and union types to interract with C programs. A package is semi-reminiscent of a C++ class, perhaps best described as a protected namespace with private and public data declarations and initialization code, as well as both private and public functions. I wonder how the other languages stack up on this kind of thing. \section {Python} It is very easy to add new types (Lance Ellinghouse has added about 20 new types of objects to Python both at the C code level as well as in Python code. Note that unlike Perl, new Python modules written in C can be dynamically loaded into a running interpreter. You don't need to relink the image. Adding a new datatype is very easy. Modifying the syntax (``adding a new keyword'') doesn't seem very easy. There could be a macro package... \section {Tcl} Its possible and well-documented and has been down well by many people in C. \chapter {Other} \section {Useful Extras} \subsection {Compilation Mechanisms} \subsection {Threads} \end {document} Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA27705 (5.65b/3.11/CWI-Amsterdam); Thu, 28 Oct 1993 10:47:52 +0100 Received: by voorn.cwi.nl with SMTP id AA16242 (5.65b/3.8/CWI-Amsterdam); Thu, 28 Oct 1993 10:47:51 +0100 Message-Id: <9310280947.AA16242=guido@voorn.cwi.nl> To: python-list@cwi.nl Subject: Bug in "rotor" module From: Guido.van.Rossum@cwi.nl X-Organization: CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Thu, 28 Oct 1993 10:47:51 +0100 Sender: Guido.van.Rossum@cwi.nl People who've been using the optional built-in module "rotor" may have noticed compiler warnings about left shifts with negative shift counts (<<-13). I've talked to the author and the original intention was for these to be right shifts (>>13). It is trivial to fix this, however there's a compatibility issue I'm concerned about: the key constructed using the fixed code looks different than the key constructed by the old, buggy code. This means that if you have written data to a file encrypted with the old rotor module, you won't be able to decrypt it using the new module. For me personally this isn't a problem, but I can imagine that there are others who have used this extensively. If this is the case for you, please speak up! We may provide a backward compatibility hack for you (basically you can use <<19, or live with the compiler warnings...). If I don't hear from anyone, I'll just fix it and release the next version with an incompatible rotor module. --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> To: python-list Subject: Bug in "rotor" module From: Guido.van.Rossum@cwi.nl X-Organization: CWI, Kruislaan 413, 1098 SJ Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Thu, 28 Oct 1993 10:47:51 +0100 Sender: guido People who've been using the optional built-in module "rotor" may have noticed compiler warnings about left shifts with negative shift counts (<<-13). I've talked to the author and the original intention was for these to be right shifts (>>13). It is trivial to fix this, however there's a compatibility issue I'm concerned about: the key constructed using the fixed code looks different than the key constructed by the old, buggy code. This means that if you have written data to a file encrypted with the old rotor module, you won't be able to decrypt it using the new module. For me personally this isn't a problem, but I can imagine that there are others who have used this extensively. If this is the case for you, please speak up! We may provide a backward compatibility hack for you (basically you can use <<19, or live with the compiler warnings...). If I don't hear from anyone, I'll just fix it and release the next version with an incompatible rotor module. --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Thu, 28 Oct 1993 16:18:43 +0100 Replied: "michael shiplett <michael.shiplett@umich.edu> python-list" Received: from totalrecall.rs.itd.umich.edu by charon.cwi.nl with SMTP id AA08604 (5.65b/3.11/CWI-Amsterdam); Thu, 28 Oct 1993 16:07:31 +0100 Received: from enchanter.ifs.umich.edu by totalrecall.rs.itd.umich.edu (5.67/2.2) with SMTP id AA10763; Thu, 28 Oct 93 11:07:26 -0400 Message-Id: <9310281507.AA10763@totalrecall.rs.itd.umich.edu> To: python-list@cwi.nl Subject: md5 module From: michael shiplett <michael.shiplett@umich.edu> Date: Thu, 28 Oct 1993 11:07:26 -0400 Sender: walrus@umich.edu Hello, I'm new to the list & to python. I did look, but to no avail, in the source distribution for information on the following, so I hope this isn't something that's in a FAQ I haven't found. I am trying to compile 0.9.9 on several platforms (rs_aix32, sun4m_412, & next_mach30). I've been able to build the rs_aix32 preliminary interpreter using gcc-2.4.5 without much difficulty (some extra preprocessor defines & some "#ifdef _AIX"). I did, however, have problems compiling the md5 module. I have RFC-1321 & have successfully built & tested mddriver. Have I completely missed something while configuring or are the following actually errors/oversights/typos? - the Makefile tells the user that md5 code is available in "md5.doc" rsa.com. At least as of this writing, the file is "//rsa.com/pub/md5.txt". This file is actually just RFC-1321. Perhaps reference should also be made to RFC-1321 as RFCs are readily available (and I assume this one is as well). - the Makefile states md5c.c is needed. The RFC contains md5c.c. This is also true of the object file (which the Makefile gives as md5.o). - global.h from the md5 code is not #included (necessary for UINT4) - md5_digest calls MD5Final with only one argument (MD5_CTX mdContext) - also in md5_digest, there is a reference to the "digest" member of mdContext (declared as above). MD5_CTX in my versions of RFC-1321, md5.txt, and RSAREF does not contain a digest member. - the "/* Really static, forward */" declarations in md5module.c, mpzmodule.c, & Fontobject.c (and probably other files which I didn't use) do not work. Gcc creates the .o but the AIX ld says the symbols are not defined. AIX cc complains about MD5type (and the other types for other modules) being redeclared. I had to '#ifndef _AIX' the 'static' modifier. I did manage to fixup md5module.c so the rsademo.py script apparently succeeded (only output was "Generating small primes list...") on the rs_aix32 machine. comments welcomed, michael Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA08855 (5.65b/3.11/CWI-Amsterdam); Thu, 28 Oct 1993 16:18:43 +0100 Received: by voorn.cwi.nl with SMTP id AA17506 (5.65b/3.8/CWI-Amsterdam); Thu, 28 Oct 1993 16:18:43 +0100 Message-Id: <9310281518.AA17506=guido@voorn.cwi.nl> To: michael shiplett <michael.shiplett@umich.edu> Cc: python-list@cwi.nl Subject: Re: md5 module In-Reply-To: Your message of "Thu, 28 Oct 1993 11:07:26 MET." <9310281507.AA10763@totalrecall.rs.itd.umich.edu> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Thu, 28 Oct 1993 16:18:43 +0100 Sender: Guido.van.Rossum@cwi.nl > [Michael Shipless complains about the md5 module] All I can say to my defense is that I didn't write the md5 module. Maybe it worked once and now the interface has subtly changed? Anyway, in the next release I'll fix the bugs, change the reference to RFC 1321, and include the md5c.c from the RFC in the src directory. How does this sound? > I did manage to fixup md5module.c so the rsademo.py script > apparently succeeded (only output was "Generating small primes > list...") on the rs_aix32 machine. That is indeed the only output to be expected. This script is mostly intended to be read (it is about the only documentation on the rsa interface...), not to be executed. --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Fri, 29 Oct 1993 11:43:16 +0100 Replied: ""Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Bill Janssen <janssen@parc.xerox.com>, python-list@cwi.nl" Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA09278 (5.65b/3.11/CWI-Amsterdam); Thu, 28 Oct 1993 16:41:27 +0100 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa26673; 28 Oct 93 11:41 EDT Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA14219; Thu, 28 Oct 1993 11:41:03 -0400 Date: Thu, 28 Oct 1993 11:41:03 -0400 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199310281541.AA14219@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: Bill Janssen <janssen@parc.xerox.com>, python-list@cwi.nl Subject: Re: obtaining the reversal of a sequence? While elvis.med.virginia.edu was getting it's disks scrubbed and cleaned, I missed the original question that started the thread about range and reverse. On Oct 20, 23:27, Bill Janssen wrote: > > I've encountered the problem where I'd like to have a sequence that is > traversed in both directions equally frequently. It's a display list, and > is traversed from back to front, to paint the window, and from front to > back, to find the innermost element enclosing a point. > > Clearly, the ``for foo in x'' construct works well for one of the two > cases, but what's the efficient way to traverse the list in reverse order? > The best I can come up with is: > > tmp = list[:] > tmp.reverse() > for x in tmp: > blah... > > and that's so inefficient I believe there must be some trick tucked away > to make this easier. > > Bill > > > -- End of excerpt from Bill Janssen <janssen@parc.xerox.com> But playing around with pseudo-sequences ( in my prev. posts ) suggests a trick: class Rev: def __init__( self, seq ): self.forw = seq self.back = self def __len__( self ): return len( self.forw ) def __getitem__( self, j ): return self.forw[ -( j + 1 ) ] def __repr__( self ): return '<reverse of sequence: ' + repr(self.forw) +' >' It works on mutable or inmutable sequences. >>> for c in Rev( 'Hello World!' ) : sys.stdout.write( c ) ... else: sys.stdout.write( '\n' ) ... !dlroW olleH >>> The .forw is so you can use anonymous sequences in init, and still keep a reference the forward sequence. ) If you give it a non-anonymous mutable sequence, the reverse sequence will track the updated values. ( but not reassignment! - another good reason to use anonymous values in creating the sequence to avoid confusion. Maybe it should be change to copy input sequence to break the connection completely ? ) >>> nnn = range( 0, 3 ) >>> rnn = Rev( nnn ) >>> for n in rnn: print n ... 2 1 0 >>> for n in range( 4, 6 ): nnn.append( n ) # update nnn ... >>> for n in rnn: print n # prints reversed updated values ... 5 4 2 1 0 >>> nnn = nnn[1:-1] >>> nnn [1, 2, 4] >>> for n in rnn: print n # prints reversed values of old nnn ... 5 4 2 1 0 >>> I'll leave it to Guido or someone else to figure out how this compares effeciency wise with the other solutions. ToDo's: repr() ought to return a more natural representation, but then it has to check for type of argument to know whether to wrap the reversed values in "[]" or "()" or something else or nothing. Add more methods to make rseq.back completely comparable to rseq.forw. e.g. rseq.back.append( ) would insert a value at the BEGINNING of rseq.forw. , etc. Also note to Terrence Brannon and others who have complained about strings being non-mutable: you can probably tell from these various pseudo-sequences that it would be pretty easy to make a mutable-string class. It isn't something I've felt as a requirement, but since it's so easy, maybe we ought to put one in the standard library. Right now I'm more interested in figuring out a more natural way of expressing regular expressions and other non-regexp patterns ( like matching parends. ) using operators on character set classes and pattern classes instead of characters with special meanings that may or may not have to be escaped. i.e. something like: Any( letters ) + Any( letters ) * 5 + Any( digits + '_$' ) * 3 ( where letters and digits are imported from string, and 'Any' would be a class constructor. ) translating into regexp: [a-zA-Z][a-zA-A]*5[0-9]*3 ( where *5 means 0-5 occurances - a specification feature I've not seen in all regexp modules. ) Any comments on the usefulness of this sort of interface to regexp, or the desired syntax or semantics ? - Steve Majewski Replied: Fri, 29 Oct 1993 10:46:55 +0100 Replied: "michael shiplett <michael.shiplett@umich.edu> " Received: from totalrecall.rs.itd.umich.edu by charon.cwi.nl with SMTP id AA10798 (5.65b/3.11/CWI-Amsterdam); Thu, 28 Oct 1993 17:42:15 +0100 Received: from enchanter.ifs.umich.edu by totalrecall.rs.itd.umich.edu (5.67/2.2) with SMTP id AA16029; Thu, 28 Oct 93 12:42:13 -0400 Message-Id: <9310281642.AA16029@totalrecall.rs.itd.umich.edu> To: Guido.van.Rossum@cwi.nl Subject: Re: md5 module In-Reply-To: Your message of Thu, 28 Oct 1993 16:18:43 +0100. <9310281518.AA17506=guido@voorn.cwi.nl> From: michael shiplett <michael.shiplett@umich.edu> Date: Thu, 28 Oct 1993 12:42:12 -0400 Sender: walrus@umich.edu "gvr" == Guido.van.Rossum <Guido.van.Rossum@cwi.nl> writes: > [Michael Shiplett complains about the md5 module] gvr> All I can say to my defense is that I didn't write the md5 module. gvr> Maybe it worked once and now the interface has subtly changed? I didn't mean to make it sound like complaining so much as things which seemed not quite right. Being new to python, I wasn't sure if it was a problem specific to my configuration or the md5 module itself. Trying to fix the md5 module, I've learned my way around the rsa.com site & even picked up a couple PEM packages, so it's been time well spent. gvr> Anyway, in the next release I'll fix the bugs, change the reference to gvr> RFC 1321, and include the md5c.c from the RFC in the src directory. gvr> How does this sound? Looking at the copyright notice, I think including the RFC files is okay, provided your docs identify the software as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm." The files global.h (rename to md5global.h???) & md5.h should be included as well. Bundling all the md5 support package seems like a good thing to me. Have there been any other comments about the extern declarations of static functions causing problems for linkers? I haven't tested them on the NeXT yet. In case you're interested, I've appended my changes for the md5 module. Now all I need is some time to learn how to use python :) thanks for the rapid feedback, michael *** md5module.distrib Thu Oct 28 08:34:30 1993 --- md5module.c Thu Oct 28 12:29:17 1993 *************** *** 31,36 **** --- 31,37 ---- #include "allobjects.h" #include "modsupport.h" /* For getargs() etc. */ + #include "global.h" /* UINT4 */ #include "md5.h" typedef struct { OB_HEAD *************** *** 128,150 **** return None; } /* md5_update() */ static object * md5_digest(self, args) md5object *self; object *args; { MD5_CTX mdContext; ! stringobject *strobjp; if (!getnoarg(args)) return NULL; /* make a temporary copy, and perform the final */ mdContext = self->md5; ! MD5Final(&mdContext); ! return newsizedstringobject((char *)mdContext.digest, 16); } /* md5_digest() */ static object * md5_copy(self, args) --- 129,155 ---- return None; } /* md5_update() */ + #define DIGESTLEN 16 /* this is used twice--walrus@umich.edu */ static object * md5_digest(self, args) md5object *self; object *args; { + MD5_CTX mdContext; ! char aDigest[DIGESTLEN]; ! if (!getnoarg(args)) return NULL; /* make a temporary copy, and perform the final */ mdContext = self->md5; ! MD5Final(aDigest, &mdContext); ! return newsizedstringobject((char *)aDigest, DIGESTLEN); } /* md5_digest() */ + #undef DIGESTLEN static object * md5_copy(self, args) *************** *** 181,188 **** return findmethod(md5_methods, (object *)self, name); } /* md5_getattr() */ ! ! static typeobject MD5type = { OB_HEAD_INIT(&Typetype) 0, /*ob_size*/ "md5", /*tp_name*/ --- 186,195 ---- return findmethod(md5_methods, (object *)self, name); } /* md5_getattr() */ ! #ifndef _AIX ! static ! #endif ! typeobject MD5type = { OB_HEAD_INIT(&Typetype) 0, /*ob_size*/ "md5", /*tp_name*/ Replied: Fri, 29 Oct 1993 11:20:59 +0100 Replied: ""Steven D. Majewski" <sdm7g@galen.med.virginia.edu> python-list@cwi.nl" Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA11271 (5.65b/3.11/CWI-Amsterdam); Thu, 28 Oct 1993 18:02:13 +0100 Received: from galen.med.virginia.edu by uvaarpa.virginia.edu id aa12226; 28 Oct 93 13:02 EDT Received: by galen.med.Virginia.EDU (5.67a8/1.34) id AA22753; Thu, 28 Oct 1993 13:02:08 -0400 Date: Thu, 28 Oct 1993 13:02:08 -0400 From: "Steven D. Majewski" <sdm7g@galen.med.virginia.edu> Message-Id: <199310281702.AA22753@galen.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: python-list@cwi.nl Subject: Rev() with better repr [and complaint about pedantic typechecking] Here's Rev() with a better __repr__() method. WH = Rev( 'Hello World!' ) print WH.forw, WH.back nnn = Rev( range( 1, 10 ) ) print nnn.forw print nnn produces output: Hello World! !dlroW olleH [1, 2, 3, 4, 5, 6, 7, 8, 9] [9, 8, 7, 6, 5, 4, 3, 2, 1] >>>rrr = Rev( nnn ) >>>rrr <1, 2, 3, 4, 5, 6, 7, 8, 9> # NOT [1, 2, ... 9] i.e. it doesn't check: if type(self) == type( Rev([]) ) && self.__class__ == Rev( [] ).__class__ but THAT belongs to an OLD thread... WHICH brings up the need for building a list of values for joinfields which doen't work on a pseudo sequence object: >>>joinfields( Rev( string.split( 'This is a test' )), ':::' ) Stack backtrace (innermost last): File "<stdin>", line 1 TypeError: first argument must be list/tuple Unnecessarily pedantic typechecking ? Not in string.py (as far as I can tell). It must be from the internal strop version. Is there any way to import the joinfields from string.py over the one in strop module ? ( Or is the solution to fix strop's joinfields ? ) Needs and __add__ method before you can "print WH.forw + WH.back". - Steve #----------- from string import joinfields class Rev: def __init__( self, seq ): self.forw = seq self.back = self def __len__( self ): return len( self.forw ) def __getitem__( self, j ): return self.forw[ -( j + 1 ) ] def __repr__( self ): seq = self.forw if type(seq) == type( [] ) : wrap = '[]' sep = ', ' elif type(seq) == type( () ) : wrap = '()' sep = ', ' elif type(seq) == type( '' ) : wrap = '' sep = '' else: wrap = '<>' sep = ', ' outstrs = [] for item in self.back : outstrs.append( str( item ) ) return wrap[:1] + joinfields( outstrs, sep ) + wrap[-1:] Replied: Fri, 29 Oct 1993 11:31:58 +0100 Replied: ""Steven D. Majewski" <sdm7g@galen.med.virginia.edu> " Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA14596 (5.65b/3.11/CWI-Amsterdam); Thu, 28 Oct 1993 22:40:43 +0100 Received: from galen.med.virginia.edu by uvaarpa.virginia.edu id aa26401; 28 Oct 93 17:40 EDT Received: by galen.med.Virginia.EDU (5.67a8/1.34) id AA35634; Thu, 28 Oct 1993 17:40:32 -0400 Date: Thu, 28 Oct 1993 17:40:32 -0400 From: "Steven D. Majewski" <sdm7g@galen.med.virginia.edu> Message-Id: <199310282140.AA35634@galen.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: python-list@cwi.nl Subject: Re: Rev() with better repr [and complaint about pedantic typechecking] I wrote ( re: difference in string.joinfields vs. strop.joinfields ) > > Not in string.py (as far as I can tell). It must be from the internal > strop version. Is there any way to import the joinfields from > string.py over the one in strop module ? ( Or is the solution > to fix strop's joinfields ? ) > I didn't actually mean that question the way it was phrased. [ Well - yes, I *DID* mean it at the time, but I wasn't thinking! :-) ] There's a clear way HOW to import string.joinfields rather than strop.joinfields: either edit the "try: from strop import *" line out of strings.py, or copy join & joinfields in another file ( join.py ). What I really meant was: (1) does anyone else besides me really CARE that they don't work identically? (2) and is the "correct & standard" fix to distinguish the two more clearly ( a "generic" join and a _s_t_r_i_n_g_.join[fields], or to make strop.join[fields] work like string.join[fields] ? It wouldn't work generically for what I wanted to do with repr, since I didn't want to join the values but the repr's of the values. But it WOULD be nice if string and sequence functions worked for pseudo-strings and pseudo-sequence object classes. For example - if I actually wrote a mutable string class, I would expect string.split to work on it. ( strop.split won't. ) Finally: Maybe a better repr for Rev is: Rev( repr( Rev( seq ).forw ) ) i.e. just the reverse of the string-representation of the sequence: >>> Rev( repr( Rev( [1,2,3] ).forw ) ) ]3 ,2 ,1[ >>> Rev( repr( Rev( (1,2,3) ).forw ) ) )3 ,2 ,1( >>> Rev( repr( Rev( '123' ).forw ) ) '321' >>> Looks a little strange, but it indicates, for tuples and lists, that they really *aren't* tuples or lists. - Steve Majewski Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA23402 (5.65b/3.11/CWI-Amsterdam); Fri, 29 Oct 1993 11:21:00 +0100 Received: by voorn.cwi.nl with SMTP id AA19226 (5.65b/3.8/CWI-Amsterdam); Fri, 29 Oct 1993 11:20:59 +0100 Message-Id: <9310291020.AA19226=guido@voorn.cwi.nl> To: "Steven D. Majewski" <sdm7g@galen.med.virginia.edu> Cc: python-list@cwi.nl Subject: Re: Rev() with better repr [and complaint about pedantic typechecking] In-Reply-To: Your message of "Thu, 28 Oct 1993 13:02:08 MET." <199310281702.AA22753@galen.med.Virginia.EDU> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Fri, 29 Oct 1993 11:20:59 +0100 Sender: Guido.van.Rossum@cwi.nl > WHICH brings up the need for building a list of values for joinfields > which doen't work on a pseudo sequence object: > > >>>joinfields( Rev( string.split( 'This is a test' )), ':::' ) > Stack backtrace (innermost last): > File "<stdin>", line 1 > TypeError: first argument must be list/tuple > > Unnecessarily pedantic typechecking ? > > Not in string.py (as far as I can tell). It must be from the internal > strop version. Is there any way to import the joinfields from > string.py over the one in strop module ? ( Or is the solution > to fix strop's joinfields ? ) strop.joinfields should be fixed (and it appears not too difficult). If you don't want the strop version, you'll have to copy string.py to string_in_python.py, take the strop reference out, and use that... However, note that in general updating all built-in functions that currently only take lists and/or tuples as arguments might prove a major undertaking... There is much more to check and the reference count handling is different... Some time... When I retire... --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> To: "Steven D. Majewski" <sdm7g@galen.med.virginia.edu> Subject: Re: Rev() with better repr [and complaint about pedantic typechecking] In-reply-to: Your message of "Thu, 28 Oct 1993 17:40:32 MET." <199310282140.AA35634@galen.med.Virginia.EDU> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Fri, 29 Oct 1993 11:31:58 +0100 Sender: guido > But it WOULD be nice if string and sequence functions worked for > pseudo-strings and pseudo-sequence object classes. For example - > if I actually wrote a mutable string class, I would expect > string.split to work on it. ( strop.split won't. ) Well it is possible in most cases to write Python code to work irrespective of the actual sequence type used. It takes a little care, e.g. you must use a[:0] (where a is the argument of unknown sequence type) instead of an empty value of a specific type. I don't know if all the code in string.py is correct in this respect; I suspect not, but most of it will be okay -- on the other hand it is only intended to work on strings so who cares. I suppose an appropriate subset of the routines from string.py could be provided as sequence.py (totally avoiding the "from strop import *" issue). On the other hand, as I wrote in my previous mail, fixing strop and other built-in modules to have the same kind of genericity would be difficult. Strop was designed to implement string manipulations as fast as possible by exploiting the C representation; perhaps a seqop module could be written which does somilar things for generic sequences. Any volunteers? --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA23746 (5.65b/3.11/CWI-Amsterdam); Fri, 29 Oct 1993 11:43:17 +0100 Received: by voorn.cwi.nl with SMTP id AA19339 (5.65b/3.8/CWI-Amsterdam); Fri, 29 Oct 1993 11:43:17 +0100 Message-Id: <9310291043.AA19339=guido@voorn.cwi.nl> To: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Cc: Bill Janssen <janssen@parc.xerox.com>, python-list@cwi.nl Subject: Re: obtaining the reversal of a sequence? In-Reply-To: Your message of "Thu, 28 Oct 1993 11:41:03 MET." <199310281541.AA14219@elvis.med.Virginia.EDU> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Fri, 29 Oct 1993 11:43:16 +0100 Sender: Guido.van.Rossum@cwi.nl If speed is what you need, and you need to traverse a list backwards, there is no way (without resorting to C) to beat list.reverse() try: for item in list: ... finally: list.reverse() A close second which leaves the forward value of list accessible is rev = list[:] rev.reverse() for item in rev: ... Anything that involves maintaining the loop index in a Python variable is much slower. I personally wouldn't worry about the space overhead of the second solution, but some people might. My feeling is that by the time you have a list that's so long that a second copy of the *list* (not its items!) is a problem, *doing* anything with all of its items in a for loop will take forever -- unless you have a totally memory starved machine with a race horse of a CPU... > Also note to Terrence Brannon and others who have complained about > strings being non-mutable: you can probably tell from these various > pseudo-sequences that it would be pretty easy to make a mutable-string > class. It isn't something I've felt as a requirement, but since it's > so easy, maybe we ought to put one in the standard library. There is already something like this: the built-in array module (which is currently optional but should be part of every Python interpreter nevertheless). array.array('c') creates an empty array of characters which supports list-like operations (including append & insert). The only drawback is that array objects aren't acceptable to built-in functions requiring a string, and e.g. file.read() doesn't return an array so you would have to copy it (e.g. using array.array('c', file.read()). --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Sat, 30 Oct 1993 01:28:55 +0100 Replied: "Bill Janssen <janssen@parc.xerox.com> python-list@cwi.nl" Received: from alpha.Xerox.COM by charon.cwi.nl with SMTP id AA02675 (5.65b/3.11/CWI-Amsterdam); Fri, 29 Oct 1993 22:07:27 +0100 Received: from holmes.parc.xerox.com ([13.1.100.162]) by alpha.xerox.com with SMTP id <11994(2)>; Fri, 29 Oct 1993 14:07:02 PDT Received: by holmes.parc.xerox.com id <16134>; Fri, 29 Oct 1993 14:06:53 -0700 Received: from Messages.7.15.N.CUILIB.3.45.SNAP.NOT.LINKED.holmes.parc.xerox.com.sun4.41 via MS.5.6.holmes.parc.xerox.com.sun4_41; Fri, 29 Oct 1993 14:06:42 -0700 (PDT) Message-Id: <ggoMLWUB0KGW42rKQi@holmes.parc.xerox.com> Date: Fri, 29 Oct 1993 14:06:42 PDT Sender: Bill Janssen <janssen@parc.xerox.com> From: Bill Janssen <janssen@parc.xerox.com> To: python-list@cwi.nl Subject: recursive internal function Next question: how do I write something like the function foo(): def bar (x): def foo (y): if (y > 100): return ... do something with y... foo (y*2) ... do something with x... foo(x*3) bar(1) I suppose I just can't. Bill To: Bill Janssen <janssen@parc.xerox.com> cc: python-list@cwi.nl Subject: Re: recursive internal function In-reply-to: Your message of "Fri, 29 Oct 1993 14:06:42 MDT." <ggoMLWUB0KGW42rKQi@holmes.parc.xerox.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Sat, 30 Oct 1993 01:28:55 +0100 Sender: guido > Next question: how do I write something like the function foo(): > > def bar (x): > > def foo (y): > > if (y > 100): return > ... do something with y... > foo (y*2) > > ... do something with x... > foo(x*3) > > bar(1) > > I suppose I just can't. Well... You could add "global foo" before the "def foo...", but I suppose it would defeat the purpose of making foo a local function. Alternatively, you could define and instantiate a local class with a recursive method foo(). But by the time you're doing that, you may be better off structuring your whole program as a class instead of as a module with functions... The moral of this story? You can trade globals for classes. Or perhaps: don't try to write Pascal in Python ;-) --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA04458 (5.65b/3.11/CWI-Amsterdam); Sat, 30 Oct 1993 01:28:56 +0100 Received: by voorn.cwi.nl with SMTP id AA21487 (5.65b/3.8/CWI-Amsterdam); Sat, 30 Oct 1993 01:28:55 +0100 Message-Id: <9310300028.AA21487=guido@voorn.cwi.nl> To: Bill Janssen <janssen@parc.xerox.com> Cc: python-list@cwi.nl Subject: Re: recursive internal function In-Reply-To: Your message of "Fri, 29 Oct 1993 14:06:42 MDT." <ggoMLWUB0KGW42rKQi@holmes.parc.xerox.com> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Sat, 30 Oct 1993 01:28:55 +0100 Sender: Guido.van.Rossum@cwi.nl > Next question: how do I write something like the function foo(): > > def bar (x): > > def foo (y): > > if (y > 100): return > ... do something with y... > foo (y*2) > > ... do something with x... > foo(x*3) > > bar(1) > > I suppose I just can't. Well... You could add "global foo" before the "def foo...", but I suppose it would defeat the purpose of making foo a local function. Alternatively, you could define and instantiate a local class with a recursive method foo(). But by the time you're doing that, you may be better off structuring your whole program as a class instead of as a module with functions... The moral of this story? You can trade globals for classes. Or perhaps: don't try to write Pascal in Python ;-) --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Wed, 03 Nov 1993 10:45:54 +0100 Replied: "Mats.Lidell@eua.ericsson.se (Mats Lidell) python-list@cwi.nl" Received: from mailgate.ericsson.se by charon.cwi.nl with SMTP id AA10767 (5.65b/%I%/CWI-Amsterdam); Wed, 3 Nov 1993 08:42:04 +0100 Received: from eua.ericsson.se by mailgate.ericsson.se (4.1/SMI-4.1-MAILGATE1.14) id AA29012; Wed, 3 Nov 93 08:42:00 +0100 Received: from ms.eua.ericsson.se by eua.ericsson.se (4.1/EUA-2.1) id AA21893; Wed, 3 Nov 93 08:41:58 +0100 Received: from euas09c18.eua.ericsson.se by ms.eua.ericsson.se (4.1/MS-2.1) id AA22812; Wed, 3 Nov 93 08:41:55 +0100 From: Mats.Lidell@eua.ericsson.se (Mats Lidell) Received: by euas09c18.eua.ericsson.se (4.1/client-1.3) id AA03493; Wed, 3 Nov 93 08:41:54 +0100 Date: Wed, 3 Nov 93 08:41:54 +0100 Message-Id: <9311030741.AA03493@euas09c18.eua.ericsson.se> To: python-list@cwi.nl Subject: Reading binary data from a file. Comments: Hyperbole mail buttons accepted, v3.09. Hi Folks, Just found myself wanting to do this: Integer = f.read(4) Yes. I have an integer (in binary) on a file and I know that my machine representation of this interger is 4 bytes. So I want to read these 4 bytes and convert them into a python integer. Is there some support for this or do I have to do a conversion function? %% Mats Replied: Wed, 03 Nov 1993 10:26:48 +0100 Replied: "Mats.Lidell@eua.ericsson.se (Mats Lidell) Python Mailing List <python-list@cwi.nl>" Received: from mailgate.ericsson.se by charon.cwi.nl with SMTP id AA11496 (5.65b/%I%/CWI-Amsterdam); Wed, 3 Nov 1993 09:48:52 +0100 Received: from eua.ericsson.se by mailgate.ericsson.se (4.1/SMI-4.1-MAILGATE1.14) id AA01229; Wed, 3 Nov 93 09:48:44 +0100 Received: from ms.eua.ericsson.se by eua.ericsson.se (4.1/EUA-2.1) id AA24345; Wed, 3 Nov 93 09:48:43 +0100 Received: from euas09c18.eua.ericsson.se by ms.eua.ericsson.se (4.1/MS-2.1) id AA02543; Wed, 3 Nov 93 09:48:42 +0100 From: Mats.Lidell@eua.ericsson.se (Mats Lidell) Received: by euas09c18.eua.ericsson.se (4.1/client-1.3) id AA04289; Wed, 3 Nov 93 09:48:41 +0100 Date: Wed, 3 Nov 93 09:48:41 +0100 Message-Id: <9311030848.AA04289@euas09c18.eua.ericsson.se> To: Python Mailing List <python-list@cwi.nl> Subject: Variable arguments in modules Comments: Hyperbole mail buttons accepted, v3.09. Hi Folks, A variable number of arguments to a C-function isn't that unusual. (At least I have a C-library that I would like to interface to python that has a lot of functions that take variable number of arguments.) Unfortunately it seems like the support for extension modules written in C currently doesn't support this. Right? I guess I can always write a C-layer with fixed number argument functions that concatenates the arguments and a corresponding python wrapper but that seems a bit silly. Q1: Is there some neat way to do this that I'm missing? Q2: Any experiences from the list with this problem would be appreciated? (source ;-) %% Mats Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA12051 (5.65b/%I%/CWI-Amsterdam); Wed, 3 Nov 1993 10:26:49 +0100 Received: by voorn.cwi.nl with SMTP id AA02821 (5.65b/3.8/CWI-Amsterdam); Wed, 3 Nov 1993 10:26:49 +0100 Message-Id: <9311030926.AA02821=guido@voorn.cwi.nl> To: Mats.Lidell@eua.ericsson.se (Mats Lidell) Cc: Python Mailing List <python-list@cwi.nl> Subject: Re: Variable arguments in modules In-Reply-To: Your message of "Wed, 03 Nov 1993 09:48:41 MET." <9311030848.AA04289@euas09c18.eua.ericsson.se> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Wed, 03 Nov 1993 10:26:48 +0100 Sender: Guido.van.Rossum@cwi.nl > A variable number of arguments to a C-function isn't that unusual. (At > least I have a C-library that I would like to interface to python that > has a lot of functions that take variable number of arguments.) > Unfortunately it seems like the support for extension modules written > in C currently doesn't support this. Right? I assume you're thinking of making a Python wrapper for a printf()-like function? The problem here is that C doesn't support this in a portable general manner (in fact that's why vprintf() et al. were invented). There is no way to "break open" the calling sequence. (I.e. C doesn't have an equivalent to Python's "apply()".) > I guess I can always write a C-layer with fixed number argument > functions that concatenates the arguments and a corresponding python > wrapper but that seems a bit silly. Yes I guess the closest you can get is something like switch (gettuplesize(args)) { case 0: foo(); break; case 1: foo(getintvalue(gettupleitem(args, 0)), getintvalue(gettupleitem(args, 1))); break; /* etc. */ } This assumes that all arguments are of a fixed type (i.e. printf() would still be impossible to do right protably, since there are compilers that pass floats or doubles in a different way than ints). Note that you can set the third element of the "struct methodlist" to 1 to indicate that the Python argument list should always be passed as a tuple, instead of passing NULL for no arguments and the argument itself for one argument as is the default. --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA12364 (5.65b/%I%/CWI-Amsterdam); Wed, 3 Nov 1993 10:45:56 +0100 Received: by voorn.cwi.nl with SMTP id AA02905 (5.65b/3.8/CWI-Amsterdam); Wed, 3 Nov 1993 10:45:55 +0100 Message-Id: <9311030945.AA02905=guido@voorn.cwi.nl> To: Mats.Lidell@eua.ericsson.se (Mats Lidell) Cc: python-list@cwi.nl Subject: Re: Reading binary data from a file. In-Reply-To: Your message of "Wed, 03 Nov 1993 08:41:54 MET." <9311030741.AA03493@euas09c18.eua.ericsson.se> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Wed, 03 Nov 1993 10:45:55 +0100 Sender: Guido.van.Rossum@cwi.nl > Just found myself wanting to do this: > > Integer = f.read(4) > > Yes. I have an integer (in binary) on a file and I know that my > machine representation of this interger is 4 bytes. So I want to read > these 4 bytes and convert them into a python integer. Is there some > support for this or do I have to do a conversion function? Two possible ways, using different (optional, but highly recommended) built-in modules: (1) Using module struct, you can convert almost any binary data (in your host's format and byte order) to Python. In this case it would be: import struct (Integer,) = struct.unpack('l', f.read(4)) This is the appropriate method if you are reading something like a header structure; the format string can specify a list of types describing the header, e.g. 'hhl' would be two shorts and a long, converted to a triple of three Python integers. Notes: (a) struct.unpack() always returns a tuple, hence the funny left-hand side of the assignment (b) the choice of a format letter is machine dependent -- 'l' is a machine 'long' (usually 4 bytes but can be 8 e.g. on DEC alpha or HP snake); 'i' is a machine 'int' (usually 4 bytes but can be 2 e.g. on Mac or PC) (c) there is currently no way to specify an alternate byte order (2) Using module array, you can efficiently read arrays of simple data types: import array a = array.array('l') a.read(f, 1) Integer = a[0] This is the appropriate method if you want to read many items of the same type, e.g. to read a 1000 integers in one fell swoop, you would use a.read(f, 1000). The same remark about the choice of format letter applies; but there is a method to byte swap an entire array (a.byteswap()) -- currently undocumented. --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Thu, 04 Nov 1993 11:22:05 +0100 Replied: ""Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> python-list" Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA21170 (5.65b/%I%/CWI-Amsterdam); Wed, 3 Nov 1993 18:28:50 +0100 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa12804; 3 Nov 93 12:28 EST Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA19031; Wed, 3 Nov 1993 12:28:35 -0500 Date: Wed, 3 Nov 1993 12:28:35 -0500 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199311031728.AA19031@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: python-list@cwi.nl Subject: str() and repr() of sequence like classes, esp. 'array' [RFC] I was suprised when I first tried using the array module and when I typed: >>>array( 'f' ) I got back: array( 'f' ) Not what I was *expecting* to see. My puzzlement faded when I next typed: >>>array( 'f', [ 1,2,3,4,5 ] ) and got: array('f', [1.0, 2.0, 3.0, 4.0, 5.0]) Neat! The print representation is able to reproduce the object: >>> ( eval(str(array('f',[1,2,3,4,5]))) == array('f',[1,2,3,4,5]) ) 1 An admirable goal. However - In some of the example sequence-like classes I have thrown together, I have tended towards trying to make the new classes behave generally like the objects they are trying to replace. Well - except for that ") (" , "] [" business for reverse sequences. Maybe I haven't been consistant with that rule, but I've played around with the technique enough to see that it, also is a useful feature. And even there, though I was willing to accept ') 3 ,2 ,1 (' as the reverse of '( 1,2,3 )', I was trying at the same time to get "Hello World!" to be "!dlroW olloH" . - I think I was starting to graple with the "correct" way to distinguish the behaviour of str() and repr(). [ And 'array' brings up some of the same questions.] If a mutable string is going to be "drop replacable" in a lot of proceures that expect a string, then : >>>print mutable-string-obj ought to do pretty much the same thing as: >>>print string With 'array', I have to say: >>> print array( 'c' , 'Hello World!' ).tostring() Hello World! because: >>> print array( 'c' , 'Hello World!' ) gives me: array('c', 'Hello World!') The need for this "drop replacable" behaviour is more obvious for string-like objects than for other sequence types, but I can think or other cases where we would like our replacement-classes to do a good job of impersonating their antecedents. But clearly, at other times, we WANT to either get a self-reproducing string ( like array returns ) or a bracketed type representation ( sort of like the way files are represented : "<open file '<stdin>', mode 'r' at 20083d98>" ) I assert that this sort of problem is just the place to distinguish between the strings returned by 'str()' and 'repr()' and I propose that we agree ( and document ) some conventions on how they are distinguished. My feeling is that the repr() of an object is the thing that should always be it's "true" representation, but the str() of an object should be it's most useful and convenient representation - i.e. the one that minimizes (and hides) what may be non-essential differences in classes and objects. Thus: >>>repr( array( 'f', [ 1,2,3,4,5 ] ) ) would be: array('f', [1.0, 2.0, 3.0, 4.0, 5.0]) but: >>>str( array( 'f', [ 1,2,3,4,5 ] ) ) would be: [1.0, 2.0, 3.0, 4.0, 5.0] And: >>>repr(array( 'c', 'Hello World' )) would be: array( 'c', 'Hello World' ) but: >>>str(array( 'c', 'Hello World' )) would be, simply: 'Hello World' I suspect it might also be useful in other (non-sequence) classes to distinguish between the representation that hides differences in implementation, and the representation that asserts those details. I think this proposal is in accord with current usage and how 'print' works, and how 'str()' and 'repr()' currently distinguish some objects. ( i.e. I *Don't* think anyone is going to propose that it be the other way around entirely! ) Does anyone see any problems with it ? Would anyone expect this sort of change to 'array' to produce much broken code ? - Steve Majewski (804-982-0831) <sdm7g@Virginia.EDU> - UVA Department of Molecular Physiology and Biological Physics Replied: Thu, 04 Nov 1993 11:17:34 +0100 Replied: ""Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> " Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA21596 (5.65b/%I%/CWI-Amsterdam); Wed, 3 Nov 1993 19:04:31 +0100 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa19108; 3 Nov 93 13:04 EST Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA11944; Wed, 3 Nov 1993 13:04:24 -0500 Date: Wed, 3 Nov 1993 13:04:24 -0500 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199311031804.AA11944@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: python-list@cwi.nl Subject: and one tiny question about array() ... >>> array( 'f', ( 1.0, 2.0 )) Stack backtrace (innermost last): File "<stdin>", line 1 TypeError: array initializer must be list or string Is there a reason for this restriction, or is this another example of "overly pedantic typechecking run amock" ? No offense intended to the author of the array module in either this or the previous post. I'm just trying to raise the question of exactly what sort of consistant behaviour we should expect. - Steve Majewski <sdm7g@Virginia.EDU> To: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Subject: Re: and one tiny question about array() ... In-reply-to: Your message of "Wed, 03 Nov 1993 13:04:24 MET." <199311031804.AA11944@elvis.med.Virginia.EDU> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Thu, 04 Nov 1993 11:17:35 +0100 Sender: guido > >>> array( 'f', ( 1.0, 2.0 )) > Stack backtrace (innermost last): > File "<stdin>", line 1 > TypeError: array initializer must be list or string > > Is there a reason for this restriction, or is this another > example of "overly pedantic typechecking run amock" ? It was just easier to code it with a particular concrete type in mind. I guess someday many of these restrictions will be lifted... --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> To: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> cc: python-list Subject: Re: str() and repr() of sequence like classes, esp. 'array' [RFC] In-reply-to: Your message of "Wed, 03 Nov 1993 12:28:35 MET." <199311031728.AA19031@elvis.med.Virginia.EDU> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Thu, 04 Nov 1993 11:22:05 +0100 Sender: guido Steven proposes that all objects have two methods: one for repr() (and ``) which returns something unambiguous, and one for str() which returns a pleasant string to be used by the print statement. I like the idea. It would seem to be simple to implement as well. Thanks! --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA02665 (5.65b/%I%/CWI-Amsterdam); Thu, 4 Nov 1993 11:22:05 +0100 Received: by voorn.cwi.nl with SMTP id AA06485 (5.65b/3.8/CWI-Amsterdam); Thu, 4 Nov 1993 11:22:05 +0100 Message-Id: <9311041022.AA06485=guido@voorn.cwi.nl> To: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Cc: python-list@cwi.nl Subject: Re: str() and repr() of sequence like classes, esp. 'array' [RFC] In-Reply-To: Your message of "Wed, 03 Nov 1993 12:28:35 MET." <199311031728.AA19031@elvis.med.Virginia.EDU> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Thu, 04 Nov 1993 11:22:05 +0100 Sender: Guido.van.Rossum@cwi.nl Steven proposes that all objects have two methods: one for repr() (and ``) which returns something unambiguous, and one for str() which returns a pleasant string to be used by the print statement. I like the idea. It would seem to be simple to implement as well. Thanks! --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Fri, 05 Nov 1993 10:51:37 +0100 Replied: ""Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> python-list" Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA11697 (5.65b/%I%/CWI-Amsterdam); Thu, 4 Nov 1993 18:32:34 +0100 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa27254; 4 Nov 93 12:32 EST Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA18831; Thu, 4 Nov 1993 12:32:22 -0500 Date: Thu, 4 Nov 1993 12:32:22 -0500 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199311041732.AA18831@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: python-list@cwi.nl Subject: More nits to pick with arrays ... Cc: Guido.van.Rossum@cwi.nl Note that: type(array('f')) == type(array('l')) == <type 'array'> >>> from array import array >>> f = array( 'f', range( 1, 10 )) >>> l = array( 'l', range( 1, 10 )) >>> h = array( 'h', range( 1, 10 )) >>> h array('h', [1, 2, 3, 4, 5, 6, 7, 8, 9]) >>> h[:3] array('h', [1, 2, 3]) >>> h[-3:] array('h', [7, 8, 9]) >>> h[:3] + h[-3:] #1 array('h', [1, 2, 3, 1, 2, 3]) #2 >>> f[:3] + l[-3:] #3 Stack backtrace (innermost last): File "<stdin>", line 1 TypeError: illegal argument type for built-in operation >>> Note that the statement marked #1 makes sense, but the answer ( #2 ) is incorrect. Expression #3 doesn't really make any sense when you understand the rationale of array types, but considering the relation at the top of the page, a PROGRAM ( as opposed to a reasonable person ) would have every right to expect it to work and NOT generate that exception. ( Let's assume that the program has tested type(arg1) == type(arg2) and that arg1 and arg2 both have the __getslice__ attribute, etc. ) What are the pro's and con's of making: type(array('f')) == <type 'array-f'> type(array('l')) == <type 'array-l'> ... etc. - Steve M. Replied: Fri, 05 Nov 1993 10:29:13 +0100 Replied: ""Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> " Received: from uvaarpa.Virginia.EDU by charon.cwi.nl with SMTP id AA12241 (5.65b/%I%/CWI-Amsterdam); Thu, 4 Nov 1993 18:57:07 +0100 Received: from elvis.med.virginia.edu by uvaarpa.virginia.edu id aa02326; 4 Nov 93 12:57 EST Received: by elvis.med.Virginia.EDU (5.65c/1.34) id AA18795; Thu, 4 Nov 1993 12:56:59 -0500 Date: Thu, 4 Nov 1993 12:56:59 -0500 From: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Message-Id: <199311041756.AA18795@elvis.med.Virginia.EDU> X-Mailer: Mail User's Shell (7.2.3 5/22/91) To: python-list@cwi.nl Subject: posix.listdir() broken ? On my build of Python 0.9.9 on AIX, posix.listdir() ( and I think maybe a few other posix functions ) is broken: Python 0.9.9 (Sep 7 1993). Copyright 1990, 1991, 1992, 1993 Stichting Mathematisch Centrum, Amsterdam >>> import posix >>> posix.listdir( '' ) Segmentation fault(coredump) elvis: /home/sdm7g/python $ python Python 0.9.9 (Sep 7 1993). Copyright 1990, 1991, 1992, 1993 Stichting Mathematisch Centrum, Amsterdam >>> import posix >>> posix.listdir( '.' ) Segmentation fault(coredump) elvis: /home/sdm7g/python $ Has anyone else observed a problem ? or is my build on AIX merely but profoundly broken ? - Steve M. - Steve Majewski (804-982-0831) <sdm7g@Virginia.EDU> - UVA Department of Molecular Physiology and Biological Physics Received: from inesc.inesc.pt by charon.cwi.nl with SMTP id AA15224 (5.65b/3.12/CWI-Amsterdam); Thu, 4 Nov 1993 23:15:37 +0100 Received: by inesc.inesc.pt via PTUnet/EUnet; id AB08180 (5.65c/SunOS4.1.3); Thu, 4 Nov 1993 23:15:00 +0100 Date: Thu, 4 Nov 1993 23:15:00 +0100 From: MAILER-DAEMON@inesc.inesc.pt (Mail Delivery Subsystem) Subject: Returned mail: User unknown Message-Id: <199311042215.AB08180@inesc.inesc.pt> To: guido@cwi.nl ----- Transcript of session follows ----- While talking to sabrina.inesc.pt: >>> RCPT To:<jmp@sabrina> <<< 550 <jmp@sabrina>... User unknown 550 <jmp@sabrina.inesc.pt>... User unknown ----- Unsent message follows ----- Received: from charon.cwi.nl by inesc.inesc.pt with SMTP; id AA19963 (5.65c/SunOS4.1.3); Thu, 4 Nov 1993 13:26:49 +0100 Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA02665 (5.65b/%I%/CWI-Amsterdam); Thu, 4 Nov 1993 11:22:05 +0100 Received: by voorn.cwi.nl with SMTP id AA06485 (5.65b/3.8/CWI-Amsterdam); Thu, 4 Nov 1993 11:22:05 +0100 Message-Id: <9311041022.AA06485=guido@voorn.cwi.nl> To: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Cc: python-list@cwi.nl Subject: Re: str() and repr() of sequence like classes, esp. 'array' [RFC] In-Reply-To: Your message of "Wed, 03 Nov 1993 12:28:35 MET." <199311031728.AA19031@elvis.med.Virginia.EDU> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 4079, 1009 AB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Thu, 04 Nov 1993 11:22:05 +0100 Sender: Guido.van.Rossum@cwi.nl Steven proposes that all objects have two methods: one for repr() (and ``) which returns something unambiguous, and one for str() which returns a pleasant string to be used by the print statement. I like the idea. It would seem to be simple to implement as well. Thanks! --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Replied: Fri, 05 Nov 1993 10:55:35 +0100 Replied: "Bill Janssen <janssen@parc.xerox.com> " Received: from alpha.Xerox.COM by charon.cwi.nl with SMTP id AA17637 (5.65b/3.12/CWI-Amsterdam); Fri, 5 Nov 1993 02:17:18 +0100 Received: from holmes.parc.xerox.com ([13.1.100.162]) by alpha.xerox.com with SMTP id <11756(2)>; Thu, 4 Nov 1993 17:16:55 PST Received: by holmes.parc.xerox.com id <16134>; Thu, 4 Nov 1993 17:16:44 -0800 Received: from Messages.7.15.N.CUILIB.3.45.SNAP.NOT.LINKED.holmes.parc.xerox.com.sun4.41 via MS.5.6.holmes.parc.xerox.com.sun4_41; Thu, 4 Nov 1993 17:16:39 -0800 (PST) Message-Id: <8gqOZrEB0KGWE2rRJq@holmes.parc.xerox.com> Date: Thu, 4 Nov 1993 17:16:39 PST Sender: Bill Janssen <janssen@parc.xerox.com> From: Bill Janssen <janssen@parc.xerox.com> To: python-list@cwi.nl Subject: No event for Control-Space I don't get an STDWIN event for control-space. Seems to me I should get an event of type WE_CHAR, with detail = 0. Or perhaps WE_KEY, detail = (32, 8). I also seem to get Backspace (control-H) (or WE_CHAR, detail = 7) events for Delete. Bill To: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Subject: Re: posix.listdir() broken ? In-reply-to: Your message of "Thu, 04 Nov 1993 12:56:59 MET." <199311041756.AA18795@elvis.med.Virginia.EDU> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 94079, 1090 GB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Fri, 05 Nov 1993 10:29:13 +0100 Sender: guido > Python 0.9.9 (Sep 7 1993). > Copyright 1990, 1991, 1992, 1993 Stichting Mathematisch Centrum, > Amsterdam > >>> import posix > >>> posix.listdir( '.' ) > Segmentation fault(coredump) > elvis: /home/sdm7g/python $ > > Has anyone else observed a problem ? or is my build on AIX > merely but profoundly broken ? I've never seen this before; sounds like a problem with your build or with AIX... --Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl> Received: from voorn.cwi.nl by charon.cwi.nl with SMTP id AA23403 (5.65b/3.12/CWI-Amsterdam); Fri, 5 Nov 1993 10:51:38 +0100 Received: by voorn.cwi.nl with SMTP id AA13476 (5.65b/3.8/CWI-Amsterdam); Fri, 5 Nov 1993 10:51:37 +0100 Message-Id: <9311050951.AA13476=guido@voorn.cwi.nl> To: "Steven D. Majewski" <sdm7g@elvis.med.virginia.edu> Cc: python-list@cwi.nl Subject: Re: More nits to pick with arrays ... In-Reply-To: Your message of "Thu, 04 Nov 1993 12:32:22 MET." <199311041732.AA18831@elvis.med.Virginia.EDU> From: Guido.van.Rossum@cwi.nl X-Organization: CWI (Centrum voor Wiskunde en Informatica) X-Address: P.O. Box 94079, 1090 GB Amsterdam, The Netherlands X-Phone: +31 20 5924127 (work), +31 20 6225521 (home), +31 20 5924199 (fax) Date: Fri, 05 Nov 1993 10:51:37 +0100 Sender: Guido.van.Rossum@cwi.nl > Note that: > type(array('f')) == type(array('l')) == <type 'array'> This merely means that the objects share most of the C code implementing them... > >>> from array import array > >>> f = array( 'f', range( 1, 10 )) > >>> l = array( 'l', range( 1, 10 )) > >>> h = array( 'h', range( 1, 10 )) > >>> h > array('h', [1, 2, 3, 4, 5, 6, 7, 8, 9]) > >>> h[:3] > array('h', [1, 2, 3]) > >>> h[-3:] > array('h', [7, 8, 9]) > >>> h[:3] + h[-3:] #1 > array('h', [1, 2, 3, 1, 2, 3]) #2 > >>> f[:3] + l[-3:] #3 > Stack backtrace (innermost last): > File "<stdin>", line 1 > TypeError: illegal argument type for built-in operation > >>> > > > Note that the statement marked #1 makes sense, but the answer > ( #2 ) is incorrect. #2 is a bug! Thanks for reporting this. It's fixed in 1.0... > Expression #3 doesn't really make any sense when you understand > the rationale of array types, but considering the relation at > the top of the page, a PROGRAM ( as opposed to a reasonable > person ) would have every right to expect it to work and NOT > generate that exception. ( Let's assume that the program has > tested type(arg1) == type(arg2) and that arg1 and arg2 both > have the __getslice__ attribute, etc. ) > > > What are the pro's and con's of making: > type(array('f')) == <type 'array-f'> > type(array('l')) == <type 'array-l'> > ... etc. This would be awkward, since these types all share the same implementation. Especially since I am hoping to generalize the array type to support arrays of arbitrary structures. It is no coincidence that the format string uses the same letters as the 'struct' module. I don't think that in general a program can make some superficial tests on an object and then assume to know all its properties. In this case, the array type enforces an